Merge "Update position & size of web view." into devel/master
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / toolkit-web-engine.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include "toolkit-timer.h"
19
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>
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace Adaptor
39 {
40
41 class WebEngine;
42
43 namespace
44 {
45 static WebEngine* gInstance = NULL;
46 static int gInstanceCount = 0;
47
48 bool OnGoBack();
49 bool OnGoForward();
50 bool OnLoadUrl();
51 bool OnEvaluteJavaScript();
52 bool OnClearHistory();
53
54 static void ConnectToGlobalSignal( bool (*func)() )
55 {
56   Dali::Timer timer = Dali::Timer::New( 0 );
57   timer.TickSignal().Connect( func );
58 }
59
60 static void DisconnectFromGlobalSignal( bool (*func)() )
61 {
62   Dali::Timer timer = Dali::Timer::New( 0 );
63   timer.TickSignal().Disconnect( func );
64 }
65 }
66
67 class MockWebEngineContext : public Dali::WebEngineContext
68 {
69 public:
70   MockWebEngineContext()
71     : mockModel( Dali::WebEngineContext::CacheModel::DOCUMENT_VIEWER )
72   {
73   }
74
75   Dali::WebEngineContext::CacheModel GetCacheModel() const override
76   {
77     return mockModel;
78   }
79
80   void SetCacheModel( Dali::WebEngineContext::CacheModel cacheModel ) override
81   {
82     mockModel = cacheModel;
83   }
84
85   void SetProxyUri( const std::string& uri ) override
86   {
87   }
88
89   void SetDefaultProxyAuth( const std::string& username, const std::string& password ) override
90   {
91   }
92
93   void SetCertificateFilePath( const std::string& certificatePath ) override
94   {
95   }
96
97   void DeleteWebDatabase() override
98   {
99   }
100
101   void DeleteWebStorage() override
102   {
103   }
104
105   void DeleteLocalFileSystem() override
106   {
107   }
108
109   void DisableCache( bool cacheDisabled ) override
110   {
111   }
112
113   void ClearCache() override
114   {
115   }
116
117 private:
118   Dali::WebEngineContext::CacheModel mockModel;
119 };
120
121 class MockWebEngineCookieManager : public Dali::WebEngineCookieManager
122 {
123 public:
124   MockWebEngineCookieManager()
125     : mockCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy::NO_THIRD_PARTY )
126   {
127   }
128
129   void SetCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy policy ) override
130   {
131     mockCookieAcceptPolicy = policy;
132   }
133
134   Dali::WebEngineCookieManager::CookieAcceptPolicy GetCookieAcceptPolicy() const override
135   {
136     return mockCookieAcceptPolicy;
137   }
138
139   void ClearCookies() override
140   {
141   }
142
143   void SetPersistentStorage( const std::string& path, Dali::WebEngineCookieManager::CookiePersistentStorage storage ) override
144   {
145   }
146
147 private:
148   Dali::WebEngineCookieManager::CookieAcceptPolicy mockCookieAcceptPolicy;
149 };
150
151 class MockWebEngineBackForwardListItem : public Dali::WebEngineBackForwardListItem
152 {
153 public:
154   MockWebEngineBackForwardListItem()
155     : mockUrl( "http://url" ),
156       mockTitle( "title" ),
157       mockOriginalUrl( "http://originalurl" )
158   {
159   }
160
161   std::string GetUrl() const override
162   {
163     return mockUrl;
164   }
165
166   std::string GetTitle() const override
167   {
168     return mockTitle;
169   }
170
171   std::string GetOriginalUrl() const override
172   {
173     return mockOriginalUrl;
174   }
175
176 private:
177   std::string mockUrl;
178   std::string mockTitle;
179   std::string mockOriginalUrl;
180 };
181
182 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
183 {
184 public:
185   MockWebEngineBackForwardList( )
186     : mockItem(),
187       pMockItem( &mockItem )
188   {
189   }
190
191   Dali::WebEngineBackForwardListItem& GetCurrentItem() const override
192   {
193     return *pMockItem;
194   }
195
196   Dali::WebEngineBackForwardListItem& GetItemAtIndex( uint32_t index ) const override
197   {
198     return *pMockItem;
199   }
200
201   uint32_t GetItemCount() const override
202   {
203     return 1;
204   }
205
206 private:
207   MockWebEngineBackForwardListItem mockItem;
208   WebEngineBackForwardListItem* pMockItem;
209 };
210
211 class MockWebEngineSettings : public WebEngineSettings
212 {
213 public:
214   MockWebEngineSettings()
215     : mockDefaultFontSize( 16 ),
216       mockJavaScriptEnabled( true ),
217       mockImageLoadedAutomatically( true ),
218       mockDefaultTextEncodingName()
219   {
220   }
221
222   uint32_t GetDefaultFontSize() const override
223   {
224     return mockDefaultFontSize;
225   }
226
227   void SetDefaultFontSize( uint32_t size ) override
228   {
229     mockDefaultFontSize = size;
230   }
231
232   bool IsJavaScriptEnabled() const override
233   {
234     return mockJavaScriptEnabled;
235   }
236
237   void EnableJavaScript( bool enabled ) override
238   {
239     mockJavaScriptEnabled = enabled;
240   }
241
242   bool AreImagesLoadedAutomatically() const override
243   {
244     return mockImageLoadedAutomatically;
245   }
246
247   void AllowImagesLoadAutomatically( bool automatic ) override
248   {
249     mockImageLoadedAutomatically = automatic;
250   }
251
252   std::string GetDefaultTextEncodingName() const override
253   {
254     return mockDefaultTextEncodingName;
255   }
256
257   void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override
258   {
259     mockDefaultTextEncodingName = defaultTextEncodingName;
260   }
261
262   void AllowMixedContents( bool allowed ) override
263   {
264   }
265
266   void EnableSpatialNavigation( bool enabled ) override
267   {
268   }
269
270   void EnableWebSecurity( bool enabled ) override
271   {
272   }
273
274   void AllowFileAccessFromExternalUrl( bool allowed ) override
275   {
276   }
277
278   void AllowScriptsOpenWindows( bool allowed ) override
279   {
280   }
281
282 private:
283   int mockDefaultFontSize;
284   bool mockJavaScriptEnabled;
285   bool mockImageLoadedAutomatically;
286   std::string mockDefaultTextEncodingName;
287 };
288
289 class WebEngine: public Dali::BaseObject
290 {
291 public:
292
293   WebEngine()
294     : mUrl()
295     , mCurrentPlusOnePos( 0 )
296     , mUserAgent()
297     , mEvaluating( false )
298     , mScrollPosition( 0, 0 )
299     , mScrollSize( 500, 500 )
300     , mContentSize( 500, 500 )
301   {
302     gInstanceCount++;
303     gInstance = this;
304
305     mockWebEngineSettings = new MockWebEngineSettings();
306     mockWebEngineContext = new MockWebEngineContext();
307     mockWebEngineCookieManager = new MockWebEngineCookieManager();
308     mockWebEngineBackForwardList = new MockWebEngineBackForwardList();
309   }
310
311   virtual ~WebEngine()
312   {
313     gInstanceCount--;
314     if( !gInstanceCount )
315     {
316       gInstance = NULL;
317     }
318
319     delete mockWebEngineSettings;
320     delete mockWebEngineContext;
321     delete mockWebEngineCookieManager;
322     delete mockWebEngineBackForwardList;
323   }
324
325   Dali::WebEngineSettings& GetSettings() const
326   {
327     return *mockWebEngineSettings;
328   }
329
330   Dali::WebEngineContext& GetContext() const
331   {
332     return *mockWebEngineContext;
333   }
334
335   Dali::WebEngineCookieManager& GetCookieManager() const
336   {
337     return *mockWebEngineCookieManager;
338   }
339
340   Dali::WebEngineBackForwardList& GetBackForwardList() const
341   {
342     return *mockWebEngineBackForwardList;
343   }
344
345   void LoadUrl( const std::string& url )
346   {
347     mUrl = url;
348     ConnectToGlobalSignal( &OnLoadUrl );
349   }
350
351   const std::string& GetUrl() const
352   {
353     return mUrl;
354   }
355
356   std::string GetTitle() const
357   {
358     return std::string("title");
359   }
360
361   Dali::PixelData GetFavicon() const
362   {
363     uint8_t* faviconData = new uint8_t[ 16 ];
364
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;
381
382     return Dali::PixelData::New( faviconData, 16, 2, 2,
383                                  Dali::Pixel::Format::RGBA8888,
384                                  Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
385   }
386
387   bool CanGoForward() const
388   {
389     return mHistory.size() > mCurrentPlusOnePos;
390   }
391
392   void GoForward()
393   {
394     ConnectToGlobalSignal( &OnGoForward );
395   }
396
397   bool CanGoBack() const
398   {
399     return mCurrentPlusOnePos > 1;
400   }
401
402   void GoBack()
403   {
404     ConnectToGlobalSignal( &OnGoBack );
405   }
406
407   void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
408   {
409     if( resultHandler )
410     {
411       if( !mEvaluating )
412       {
413         ConnectToGlobalSignal( &OnEvaluteJavaScript );
414       }
415       mResultCallbacks.push_back( resultHandler );
416     }
417   }
418
419   void ClearHistory()
420   {
421     ConnectToGlobalSignal( &OnClearHistory );
422   }
423
424   const std::string& GetUserAgent() const
425   {
426     return mUserAgent;
427   }
428
429   void SetUserAgent( const std::string& userAgent )
430   {
431     mUserAgent = userAgent;
432   }
433
434   void ScrollBy( int dx, int dy )
435   {
436     mScrollPosition += Dali::Vector2( dx, dy );
437     if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
438     {
439       gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
440     }
441   }
442
443   void SetScrollPosition( int x, int y )
444   {
445     mScrollPosition.x = x;
446     mScrollPosition.y = y;
447   }
448
449   Dali::Vector2 GetScrollPosition() const
450   {
451     return mScrollPosition;
452   }
453
454   Dali::Vector2 GetScrollSize() const
455   {
456     return mScrollSize;
457   }
458
459   Dali::Vector2 GetContentSize() const
460   {
461     return  mContentSize;
462   }
463
464   Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
465   {
466     return mPageLoadStartedSignal;
467   }
468
469   Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
470   {
471     return mPageLoadFinishedSignal;
472   }
473
474   Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
475   {
476     return mPageLoadErrorSignal;
477   }
478
479   Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
480   {
481     return mScrollEdgeReachedSignal;
482   }
483
484   std::string                                                mUrl;
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;
492   bool                                                       mEvaluating;
493
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;
502 };
503
504 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
505 {
506   DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
507   BaseObject& handle = webEngine.GetBaseObject();
508   return static_cast< Internal::Adaptor::WebEngine& >( handle );
509 }
510
511 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
512 {
513   DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
514   const BaseObject& handle = webEngine.GetBaseObject();
515   return static_cast< const Internal::Adaptor::WebEngine& >( handle );
516 }
517
518 namespace
519 {
520
521 bool OnGoBack()
522 {
523   DisconnectFromGlobalSignal( &OnGoBack );
524
525   if( gInstance && gInstance->CanGoBack() )
526   {
527     gInstance->mCurrentPlusOnePos--;
528   }
529   return false;
530 }
531
532 bool OnGoForward()
533 {
534   DisconnectFromGlobalSignal( &OnGoForward );
535
536   if( gInstance && gInstance->CanGoForward() )
537   {
538     gInstance->mCurrentPlusOnePos++;
539   }
540   return false;
541 }
542
543 bool OnLoadUrl()
544 {
545   DisconnectFromGlobalSignal( &OnLoadUrl );
546
547   if( gInstance )
548   {
549     if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
550     {
551       gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
552     }
553     gInstance->mHistory.push_back( gInstance->mUrl );
554     gInstance->mCurrentPlusOnePos++;
555     gInstance->mPageLoadStartedSignal.Emit( gInstance->mUrl );
556     gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
557   }
558   return false;
559 }
560
561 bool OnEvaluteJavaScript()
562 {
563   DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
564
565   if( gInstance )
566   {
567     for( auto& func : gInstance->mResultCallbacks )
568     {
569       func("undefined");
570     }
571     gInstance->mResultCallbacks.clear();
572   }
573   return false;
574 }
575
576 bool OnClearHistory()
577 {
578   DisconnectFromGlobalSignal( &OnClearHistory );
579
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;
585   }
586   return false;
587 }
588 } // namespace
589
590 } // namespace Adaptor
591
592 } // namespace Internal
593
594
595 // Dali::WebEngine Implementation
596 WebEngine::WebEngine()
597 {
598 }
599
600 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
601 : BaseHandle( internal )
602 {
603 }
604
605 WebEngine::~WebEngine()
606 {
607 }
608
609 WebEngine WebEngine::New()
610 {
611   Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
612
613   return WebEngine( baseObject );
614 }
615
616 WebEngine::WebEngine( const WebEngine& WebEngine )
617 : BaseHandle( WebEngine )
618 {
619 }
620
621 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
622 {
623   BaseHandle::operator=( webEngine );
624   return *this;
625 }
626
627 WebEngine WebEngine::DownCast( BaseHandle handle )
628 {
629   return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
630 }
631
632 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
633 {
634 }
635
636 void WebEngine::Create( int width, int height, int argc, char** argv )
637 {
638 }
639
640 void WebEngine::Destroy()
641 {
642 }
643
644 WebEngineSettings& WebEngine::GetSettings() const
645 {
646   return Internal::Adaptor::GetImplementation( *this ).GetSettings();
647 }
648
649 WebEngineContext& WebEngine::GetContext() const
650 {
651   return Internal::Adaptor::GetImplementation( *this ).GetContext();
652 }
653
654 WebEngineCookieManager& WebEngine::GetCookieManager() const
655 {
656   return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
657 }
658
659 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
660 {
661   return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
662 }
663
664 void WebEngine::LoadUrl( const std::string& url )
665 {
666   return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
667 }
668
669 std::string WebEngine::GetTitle() const
670 {
671   return Internal::Adaptor::GetImplementation( *this ).GetTitle();
672 }
673
674 Dali::PixelData WebEngine::GetFavicon() const
675 {
676   return Internal::Adaptor::GetImplementation( *this ).GetFavicon();
677 }
678
679 const std::string& WebEngine::GetUrl()
680 {
681   return Internal::Adaptor::GetImplementation( *this ).GetUrl();
682 }
683
684 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
685 {
686   Any source;
687   Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
688   return sourcePtr;
689 }
690
691 void WebEngine::LoadHtmlString( const std::string& htmlString )
692 {
693 }
694
695 void WebEngine::Reload()
696 {
697 }
698
699 void WebEngine::StopLoading()
700 {
701 }
702
703 void WebEngine::Suspend()
704 {
705 }
706
707 void WebEngine::Resume()
708 {
709 }
710
711 bool WebEngine::CanGoForward()
712 {
713   return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
714 }
715
716 void WebEngine::GoForward()
717 {
718   Internal::Adaptor::GetImplementation( *this ).GoForward();
719 }
720
721 bool WebEngine::CanGoBack()
722 {
723   return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
724 }
725
726 void WebEngine::GoBack()
727 {
728   Internal::Adaptor::GetImplementation( *this ).GoBack();
729 }
730
731 void WebEngine::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
732 {
733   Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
734 }
735
736 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler )
737 {
738 }
739
740 void WebEngine::ClearAllTilesResources()
741 {
742 }
743
744 void WebEngine::ClearHistory()
745 {
746   Internal::Adaptor::GetImplementation( *this ).ClearHistory();
747 }
748
749 const std::string& WebEngine::GetUserAgent() const
750 {
751   return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
752 }
753
754 void WebEngine::SetUserAgent( const std::string& userAgent )
755 {
756   Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
757 }
758
759 void WebEngine::ScrollBy( int dx, int dy )
760 {
761   Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
762 }
763
764 void WebEngine::SetScrollPosition( int x, int y )
765 {
766   Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
767 }
768
769 Dali::Vector2 WebEngine::GetScrollPosition() const
770 {
771   return Internal::Adaptor::GetImplementation( *this ).GetScrollPosition();
772 }
773
774 Dali::Vector2 WebEngine::GetScrollSize() const
775 {
776   return Internal::Adaptor::GetImplementation( *this ).GetScrollSize();
777 }
778
779 Dali::Vector2 WebEngine::GetContentSize() const
780 {
781   return Internal::Adaptor::GetImplementation( *this ).GetContentSize();
782 }
783
784 void WebEngine::SetSize( int width, int height )
785 {
786 }
787
788 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
789 {
790   return true;
791 }
792
793 bool WebEngine::SendKeyEvent( const KeyEvent& event )
794 {
795   return true;
796 }
797
798 void WebEngine::SetFocus( bool focused )
799 {
800 }
801
802 void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
803 {
804 }
805
806 void WebEngine::EnableVideoHole( bool enabled )
807 {
808 }
809
810 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
811 {
812   return Internal::Adaptor::GetImplementation( *this ).PageLoadStartedSignal();
813 }
814
815 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
816 {
817   return Internal::Adaptor::GetImplementation( *this ).PageLoadFinishedSignal();
818 }
819
820 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& WebEngine::PageLoadErrorSignal()
821 {
822   return Internal::Adaptor::GetImplementation( *this ).PageLoadErrorSignal();
823 }
824
825 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEdgeReachedSignal()
826 {
827   return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeReachedSignal();
828 }
829
830 } // namespace Dali;
831