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 = NULL;
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 RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
571 mNavigationPolicyDecisionCallback = callback;
574 void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
578 ConnectToGlobalSignal(&OnPlainTextReceived);
579 mPlainTextReceivedCallback = callback;
584 std::vector< std::string > mHistory;
585 size_t mCurrentPlusOnePos;
586 std::string mUserAgent;
588 Dali::WebEnginePlugin::WebEnginePageLoadCallback mPageLoadStartedCallback;
589 Dali::WebEnginePlugin::WebEnginePageLoadCallback mPageLoadFinishedCallback;
590 Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback mPageLoadErrorCallback;
591 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback mScrollEdgeReachedCallback;
592 Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback mNavigationPolicyDecisionCallback;
594 std::vector<Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback> mResultCallbacks;
597 Dali::Vector2 mScrollPosition;
598 Dali::Vector2 mScrollSize;
599 Dali::Vector2 mContentSize;
600 WebEngineBackForwardList* mockWebEngineBackForwardList;
601 WebEngineContext* mockWebEngineContext;
602 WebEngineCookieManager* mockWebEngineCookieManager;
603 WebEngineSettings* mockWebEngineSettings;
604 Dali::WebEnginePlugin::PlainTextReceivedCallback mPlainTextReceivedCallback;
607 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
609 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
610 BaseObject& handle = webEngine.GetBaseObject();
611 return static_cast< Internal::Adaptor::WebEngine& >( handle );
614 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
616 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
617 const BaseObject& handle = webEngine.GetBaseObject();
618 return static_cast< const Internal::Adaptor::WebEngine& >( handle );
626 DisconnectFromGlobalSignal( &OnGoBack );
628 if( gInstance && gInstance->CanGoBack() )
630 gInstance->mCurrentPlusOnePos--;
637 DisconnectFromGlobalSignal( &OnGoForward );
639 if( gInstance && gInstance->CanGoForward() )
641 gInstance->mCurrentPlusOnePos++;
648 DisconnectFromGlobalSignal( &OnLoadUrl );
652 if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
654 gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
656 gInstance->mHistory.push_back( gInstance->mUrl );
657 gInstance->mCurrentPlusOnePos++;
658 if (gInstance->mPageLoadStartedCallback)
660 gInstance->mPageLoadStartedCallback( gInstance->mUrl );
662 if (gInstance->mPageLoadFinishedCallback)
664 gInstance->mPageLoadFinishedCallback( gInstance->mUrl );
666 if (gInstance->mPageLoadErrorCallback)
668 gInstance->mPageLoadErrorCallback(gInstance->mUrl, WebView::LoadErrorCode::UNKNOWN);
670 if (gInstance->mNavigationPolicyDecisionCallback)
672 std::unique_ptr<Dali::WebEnginePolicyDecision> policyDecision(new MockWebEnginePolicyDecision());
673 gInstance->mNavigationPolicyDecisionCallback(std::move(policyDecision));
679 bool OnEvaluteJavaScript()
681 DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
685 for( auto& func : gInstance->mResultCallbacks )
689 gInstance->mResultCallbacks.clear();
694 bool OnClearHistory()
696 DisconnectFromGlobalSignal( &OnClearHistory );
698 if( gInstance && gInstance->mCurrentPlusOnePos ) {
699 std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
700 std::vector< std::string >().swap( gInstance->mHistory );
701 gInstance->mHistory.push_back( url );
702 gInstance->mCurrentPlusOnePos = 1;
707 bool OnPlainTextReceived()
709 DisconnectFromGlobalSignal(&OnPlainTextReceived);
712 std::string dummyResultText;
713 gInstance->mPlainTextReceivedCallback(dummyResultText);
720 } // namespace Adaptor
722 } // namespace Internal
725 // Dali::WebEngine Implementation
726 WebEngine::WebEngine()
730 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
731 : BaseHandle( internal )
735 WebEngine::~WebEngine()
739 WebEngine WebEngine::New()
741 Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
743 return WebEngine( baseObject );
746 WebEngine::WebEngine( const WebEngine& WebEngine )
747 : BaseHandle( WebEngine )
751 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
753 BaseHandle::operator=( webEngine );
757 WebEngine WebEngine::DownCast( BaseHandle handle )
759 return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
762 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
766 void WebEngine::Create( int width, int height, int argc, char** argv )
770 void WebEngine::Destroy()
774 WebEngineSettings& WebEngine::GetSettings() const
776 return Internal::Adaptor::GetImplementation( *this ).GetSettings();
779 WebEngineContext& WebEngine::GetContext() const
781 return Internal::Adaptor::GetImplementation( *this ).GetContext();
784 WebEngineCookieManager& WebEngine::GetCookieManager() const
786 return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
789 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
791 return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
794 void WebEngine::LoadUrl( const std::string& url )
796 return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
799 std::string WebEngine::GetTitle() const
801 return Internal::Adaptor::GetImplementation( *this ).GetTitle();
804 Dali::PixelData WebEngine::GetFavicon() const
806 return Internal::Adaptor::GetImplementation( *this ).GetFavicon();
809 const std::string& WebEngine::GetUrl()
811 return Internal::Adaptor::GetImplementation( *this ).GetUrl();
814 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
817 Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
821 void WebEngine::LoadHtmlString( const std::string& htmlString )
825 void WebEngine::Reload()
829 void WebEngine::StopLoading()
833 void WebEngine::Suspend()
837 void WebEngine::Resume()
841 bool WebEngine::CanGoForward()
843 return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
846 void WebEngine::GoForward()
848 Internal::Adaptor::GetImplementation( *this ).GoForward();
851 bool WebEngine::CanGoBack()
853 return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
856 void WebEngine::GoBack()
858 Internal::Adaptor::GetImplementation( *this ).GoBack();
861 void WebEngine::EvaluateJavaScript( const std::string& script, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback resultHandler )
863 Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
866 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback handler )
870 void WebEngine::ClearAllTilesResources()
874 void WebEngine::ClearHistory()
876 Internal::Adaptor::GetImplementation( *this ).ClearHistory();
879 const std::string& WebEngine::GetUserAgent() const
881 return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
884 void WebEngine::SetUserAgent( const std::string& userAgent )
886 Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
889 void WebEngine::ScrollBy( int dx, int dy )
891 Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
894 void WebEngine::SetScrollPosition( int x, int y )
896 Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
899 void WebEngine::GetScrollPosition( int& x, int& y ) const
901 Internal::Adaptor::GetImplementation( *this ).GetScrollPosition( x, y );
904 void WebEngine::GetScrollSize( int& w, int& h ) const
906 Internal::Adaptor::GetImplementation( *this ).GetScrollSize( w, h );
909 void WebEngine::GetContentSize( int& w, int& h ) const
911 Internal::Adaptor::GetImplementation( *this ).GetContentSize( w, h );
914 void WebEngine::SetSize( int width, int height )
918 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
923 bool WebEngine::SendKeyEvent( const KeyEvent& event )
928 void WebEngine::SetFocus( bool focused )
932 void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
936 void WebEngine::EnableVideoHole( bool enabled )
940 void WebEngine::RegisterPageLoadStartedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
942 Internal::Adaptor::GetImplementation( *this ).RegisterPageLoadStartedCallback(callback);
945 void WebEngine::RegisterPageLoadFinishedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
947 Internal::Adaptor::GetImplementation( *this ).RegisterPageLoadFinishedCallback(callback);
950 void WebEngine::RegisterPageLoadErrorCallback(Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback callback)
952 Internal::Adaptor::GetImplementation( *this ).RegisterPageLoadErrorCallback(callback);
955 void WebEngine::RegisterScrollEdgeReachedCallback(Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback callback)
957 Internal::Adaptor::GetImplementation( *this ).RegisterScrollEdgeReachedCallback(callback);
960 void WebEngine::RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
962 Internal::Adaptor::GetImplementation(*this).RegisterNavigationPolicyDecidedCallback(callback);
965 void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
967 Internal::Adaptor::GetImplementation(*this).GetPlainTextAsynchronously(callback);