Refactor screen-connector
[platform/core/uifw/widget-viewer-dali.git] / internal / widget_view / widget_view_impl.cpp
1 /*
2  * Samsung API
3  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Flora License, Version 1.1 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://floralicense.org/license/
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 // CLASS HEADER
19 #include <internal/widget_view/widget_view_impl.h>
20
21 // INTERNAL INCLUDES
22
23 // EXTERNAL INCLUDES
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/events/touch-data.h>
26 #include <dali/public-api/events/wheel-event.h>
27 #include <dali/public-api/images/native-image.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <dali-toolkit/public-api/visuals/visual-properties.h>
31 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
32 #include <dali/integration-api/debug.h>
33 #include <string.h>
34 #include <Ecore_Input.h>
35 #include <widget_service.h>
36 #include <widget_instance.h>
37 #include <tzplatform_config.h>
38 #include <wayland-extension/tizen-extension-client-protocol.h>
39 #include <unistd.h>
40
41 namespace Dali
42 {
43
44 namespace WidgetView
45 {
46
47 namespace Internal
48 {
49
50 namespace
51 {
52
53 #define WIDGET_VIEW_RESOURCE_DEFAULT_IMG "/widget_viewer_dali/images/unknown.png"
54
55 #if defined(DEBUG_ENABLED)
56 Integration::Log::Filter* gWidgetViewLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_WIDGET_VIEW" );
57 #endif
58
59 BaseHandle Create()
60 {
61   return Dali::BaseHandle();
62 }
63
64 // Setup properties, signals and actions using the type-registry.
65 DALI_TYPE_REGISTRATION_BEGIN( Dali::WidgetView::WidgetView, Toolkit::Control, Create );
66 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "widgetId", BOOLEAN, WIDGET_ID )
67 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "instanceId", BOOLEAN, INSTANCE_ID )
68 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "contentInfo", BOOLEAN, CONTENT_INFO )
69 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "title", BOOLEAN, TITLE )
70 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "updatePeriod", BOOLEAN, UPDATE_PERIOD )
71 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "preview", MAP, PREVIEW )
72 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "loadingText", MAP, LOADING_TEXT )
73 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "widgetStateFaulted", BOOLEAN, WIDGET_STATE_FAULTED )
74 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "permanentDelete", BOOLEAN, PERMANENT_DELETE )
75
76 // Signals
77 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetAdded", SIGNAL_WIDGET_ADDED )
78 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetDeleted", SIGNAL_WIDGET_DELETED )
79 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetCreationAborted", SIGNAL_WIDGET_CREATION_ABORTED )
80 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetContentUpdated", SIGNAL_WIDGET_CONTENT_UPDATED )
81 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetUpdatePeriodChanged", SIGNAL_WIDGET_UPDATE_PERIOD_CHANGED )
82 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetFaulted", SIGNAL_WIDGET_FAULTED )
83
84 // Actions
85 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "pauseWidget", ACTION_WIDGETVIEW_PAUSE_WIDGET );
86 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "resumeWidget", ACTION_WIDGETVIEW_RESUME_WIDGET );
87 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "cancelTouchEvent", ACTION_WIDGETVIEW_CANCEL_TOUCH_EVENT );
88 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "activateFaultedWidget", ACTION_WIDGETVIEW_ACTIVATE_FAULTED_WIDGET );
89
90 DALI_TYPE_REGISTRATION_END()
91
92 struct wl_buffer* preBuffer;
93
94 static void OnBufferUpdated( struct tizen_remote_surface *surface, uint32_t type, struct wl_buffer *buffer,
95                               int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys,
96                               const char *appid, const char *instance_id, const int pid, void *data)
97 {
98   Dali::WidgetView::Internal::WidgetView* widgetView = static_cast< Dali::WidgetView::Internal::WidgetView* >( data );
99
100   if( widgetView )
101   {
102     if( !widgetView->IsWidgetImageView() )
103     {
104       tizen_remote_surface_transfer_visibility( surface, TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE);
105
106       widgetView->CreateWidgetImageView();
107       widgetView->ConnectSignal( surface );
108     }
109
110     //get tbm surface from buffer
111     tbm_surface_h tbmSurface = static_cast< tbm_surface_h >( wl_buffer_get_user_data( buffer ) );
112     widgetView->UpdateImageSource( tbmSurface );
113   }
114
115   if( preBuffer != NULL && tizen_remote_surface_get_version( surface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION )
116   {
117     tizen_remote_surface_release( surface, preBuffer );
118   }
119
120   preBuffer = buffer;
121
122   close( img_file_fd );
123 }
124
125 static void OnBufferAdded( const char *appid, const char *instance_id, const int pid, void *data )
126 {
127 }
128
129 static void OnSurfaceRemoved( const char *appid, const char *instance_id, const int pid, void *data )
130 {
131   Dali::WidgetView::Internal::WidgetView* widgetView = static_cast< Dali::WidgetView::Internal::WidgetView* >( data );
132
133   if( widgetView )
134   {
135     widgetView->CloseRemoteSurface();
136   }
137 }
138
139 } // unnamed namespace
140
141 Dali::WidgetView::WidgetView WidgetView::New( const std::string& widgetId, const std::string& contentInfo, int width, int height, float updatePeriod )
142 {
143   // Create the implementation, temporarily owned on stack
144   IntrusivePtr< WidgetView > internalWidgetView = new WidgetView( widgetId, contentInfo, width, height, updatePeriod );
145
146   // Pass ownership to CustomActor
147   Dali::WidgetView::WidgetView widgetView( *internalWidgetView );
148
149   // Second-phase init of the implementation
150   // This can only be done after the CustomActor connection has been made...
151   internalWidgetView->Initialize();
152
153   return widgetView;
154 }
155
156 WidgetView::WidgetView()
157 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
158   mWidgetId(),
159   mInstanceId(),
160   mContentInfo(),
161   mTitle(),
162   mWidth( 0 ),
163   mHeight( 0 ),
164   mPid( 0 ),
165   mUpdatePeriod( 0.0 ),
166   mPreviewVisible( true ),
167   mStateTextVisible( true ),
168   mPermanentDelete( false ),
169   mWatcherHandle( NULL ),
170   mRemoteSurface( NULL )
171 {
172 }
173
174 WidgetView::WidgetView( const std::string& widgetId, const std::string& contentInfo, int width, int height, float updatePeriod )
175 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
176   mWidgetId( widgetId ),
177   mInstanceId(),
178   mContentInfo( contentInfo ),
179   mTitle(),
180   mWidth( width ),
181   mHeight( height ),
182   mPid( 0 ),
183   mUpdatePeriod( updatePeriod ),
184   mPreviewVisible( true ),
185   mStateTextVisible( true ),
186   mPermanentDelete( false ),
187   mWatcherHandle( NULL ),
188   mRemoteSurface( NULL )
189 {
190 }
191
192 WidgetView::~WidgetView()
193 {
194   if( !mWidgetId.empty() && !mInstanceId.empty() )
195   {
196     widget_instance_terminate( mInstanceId.c_str() );
197
198     if( mPermanentDelete )
199     {
200       widget_instance_destroy( mInstanceId.c_str() );
201     }
202   }
203 }
204
205 bool WidgetView::PauseWidget()
206 {
207   int ret = widget_instance_pause( mInstanceId.c_str() );
208   if( ret < 0 )
209   {
210     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Fail to pause widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
211     return false;
212   }
213
214   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Widget is paused (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
215
216   return true;
217 }
218
219 bool WidgetView::ResumeWidget()
220 {
221   int ret = widget_instance_resume( mInstanceId.c_str() );
222   if( ret < 0 )
223   {
224     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Fail to resume widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
225     return false;
226   }
227
228   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Widget is resumed (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
229
230   return true;
231 }
232
233 const std::string& WidgetView::GetWidgetId() const
234 {
235   return mWidgetId;
236 }
237
238 const std::string& WidgetView::GetInstanceId() const
239 {
240   return mInstanceId;
241 }
242
243 const std::string& WidgetView::GetContentInfo()
244 {
245   widget_instance_h instance;
246   char* contentInfo = NULL;
247
248   mContentInfo.clear();
249
250   if( mWidgetId.empty() || mInstanceId.empty() )
251   {
252     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Widget id (%s) or instance id (%s) is invalid.\n", mWidgetId.c_str(), mInstanceId.c_str() );
253     return mContentInfo;
254   }
255
256   instance = widget_instance_get_instance( mWidgetId.c_str(), mInstanceId.c_str() );
257   if( !instance )
258   {
259     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: widget_instance_get_instance is failed. [%s]\n", mInstanceId.c_str() );
260     return mContentInfo;
261   }
262
263   if( widget_instance_get_content( instance, &contentInfo ) < 0 )
264   {
265     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Failed to get content of widget. [%s]\n", mInstanceId.c_str() );
266     return mContentInfo;
267   }
268
269   mContentInfo = reinterpret_cast< char* >( contentInfo );
270
271   return mContentInfo;
272 }
273
274 const std::string& WidgetView::GetTitle()
275 {
276   //ToDo: We should add some codes by considering widget_viewer_evas
277   if( mTitle.empty() )
278   {
279     mTitle = widget_service_get_name( mWidgetId.c_str(), NULL );
280   }
281
282   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetTitle: title = %s\n", mTitle.c_str() );
283
284   return mTitle;
285 }
286
287 float WidgetView::GetUpdatePeriod() const
288 {
289   return mUpdatePeriod;
290 }
291
292 bool WidgetView::CancelTouchEvent()
293 {
294   if( mRemoteSurface )
295   {
296     tizen_remote_surface_transfer_touch_cancel( mRemoteSurface );
297     return true;
298   }
299
300   return false;
301 }
302
303 void WidgetView::ShowPreview( bool show )
304 {
305   if( mPreviewImage && show != mPreviewVisible )
306   {
307     mPreviewVisible = show;
308     mPreviewImage.SetVisible( show );
309   }
310 }
311
312 bool WidgetView::IsPreviewVisible()
313 {
314   return mPreviewVisible;
315 }
316
317 void WidgetView::ShowStateText( bool show )
318 {
319   if( mStateText && mStateTextVisible != show )
320   {
321     mStateTextVisible = show;
322     mStateText.SetVisible( show );
323   }
324 }
325
326 bool WidgetView::IsStateTextVisible()
327 {
328   return mStateTextVisible;
329 }
330
331 void WidgetView::ActivateFaultedWidget()
332 {
333   if( mPid < 0 )
334   {
335     // Esable preview and text
336     if( mPreviewVisible )
337     {
338       mPreviewImage.SetVisible( true );
339     }
340
341     if( mStateTextVisible )
342     {
343       mStateText.SetVisible( true );
344     }
345
346     // launch widget again
347     mPid = widget_instance_launch( mInstanceId.c_str(), (char *)mContentInfo.c_str(), mWidth, mHeight );
348     if( mPid < 0)
349     {
350       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
351
352       // Emit signal
353       Dali::WidgetView::WidgetView handle( GetOwner() );
354       mWidgetCreationAbortedSignal.Emit( handle );
355
356       return;
357     }
358
359     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
360   }
361 }
362
363 bool WidgetView::IsWidgetFaulted()
364 {
365   return mPid < 0 ? true : false;
366 }
367
368 void WidgetView::SetPermanentDelete( bool permanentDelete )
369 {
370   mPermanentDelete = permanentDelete;
371 }
372
373 bool WidgetView::IsPermanentDelete()
374 {
375   return mPermanentDelete;
376 }
377
378 void WidgetView::CreateWidgetImageView()
379 {
380   Any source;
381   mImageSource = Dali::NativeImageSource::New( source );
382   Dali::NativeImage image = Dali::NativeImage::New( *mImageSource );
383
384   mWidgetImageView = Dali::Toolkit::ImageView::New( image );
385
386   mWidgetImageView.SetParentOrigin( ParentOrigin::CENTER );
387   mWidgetImageView.SetAnchorPoint( AnchorPoint::CENTER );
388   mWidgetImageView.SetSize( mWidth, mHeight );
389
390   Self().Add( mWidgetImageView );
391
392   //EFL app should be pre multiplied image.
393   mWidgetImageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true );
394
395   // Disable preview and text
396   if( mPreviewVisible )
397   {
398     mPreviewImage.SetVisible( false );
399   }
400
401   if( mStateTextVisible )
402   {
403     mStateText.SetVisible( false );
404   }
405
406   // Emit signal
407   Dali::WidgetView::WidgetView handle( GetOwner() );
408   mWidgetAddedSignal.Emit( handle );
409
410   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::AddObjectView: ObjectView is added.\n" );
411 }
412
413 void WidgetView::RemoveObjectView()
414 {
415   // Enable preview and text
416   if( mPreviewVisible )
417   {
418     mPreviewImage.SetVisible( true );
419   }
420
421   if( mStateTextVisible )
422   {
423     mStateText.SetVisible( true );
424   }
425
426   // Emit signal
427   Dali::WidgetView::WidgetView handle( GetOwner() );
428   mWidgetDeletedSignal.Emit( handle );
429
430   mWidgetImageView.Reset();
431
432   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::RemoveObjectView: ObjectView is removed.\n" );
433 }
434
435 void WidgetView::SendWidgetEvent( int event )
436 {
437   Dali::WidgetView::WidgetView handle( GetOwner() );
438
439   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::SendWidgetEvent: event = %d widget = %s\n", event,  mWidgetId.c_str() );
440
441   // Emit signal
442   switch( event )
443   {
444     case WIDGET_INSTANCE_EVENT_UPDATE:
445     case WIDGET_INSTANCE_EVENT_EXTRA_UPDATED:
446     {
447       mWidgetContentUpdatedSignal.Emit( handle );
448       break;
449     }
450     case WIDGET_INSTANCE_EVENT_PERIOD_CHANGED:
451     {
452       mWidgetUpdatePeriodChangedSignal.Emit( handle );
453       break;
454     }
455     case WIDGET_INSTANCE_EVENT_FAULT:
456     {
457       mWidgetFaultedSignal.Emit( handle );
458       break;
459     }
460     default:
461     {
462       break;
463     }
464   }
465 }
466
467 bool WidgetView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
468 {
469   Dali::BaseHandle handle( object );
470
471   bool connected( true );
472   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( handle );
473
474   if( strcmp( signalName.c_str(), SIGNAL_WIDGET_ADDED ) == 0 )
475   {
476     widgetView.WidgetAddedSignal().Connect( tracker, functor );
477   }
478   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_DELETED ) == 0 )
479   {
480     widgetView.WidgetDeletedSignal().Connect( tracker, functor );
481   }
482   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_CREATION_ABORTED ) == 0 )
483   {
484     widgetView.WidgetCreationAbortedSignal().Connect( tracker, functor );
485   }
486   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_CONTENT_UPDATED ) == 0 )
487   {
488     widgetView.WidgetContentUpdatedSignal().Connect( tracker, functor );
489   }
490   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_UPDATE_PERIOD_CHANGED ) == 0 )
491   {
492     widgetView.WidgetUpdatePeriodChangedSignal().Connect( tracker, functor );
493   }
494   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_FAULTED ) == 0 )
495   {
496     widgetView.WidgetFaultedSignal().Connect( tracker, functor );
497   }
498   else
499   {
500     // signalName does not match any signal
501     connected = false;
502   }
503
504   return connected;
505 }
506
507 bool WidgetView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
508 {
509   bool ret = true;
510
511   Dali::BaseHandle handle( object );
512   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( handle );
513
514   if( !widgetView )
515   {
516     return false;
517   }
518
519   WidgetView& impl = GetImplementation( widgetView );
520
521   if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_PAUSE_WIDGET ) == 0 )
522   {
523     impl.PauseWidget();
524   }
525   else if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_RESUME_WIDGET ) == 0 )
526   {
527     impl.ResumeWidget();
528   }
529   else if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_CANCEL_TOUCH_EVENT ) == 0 )
530   {
531     impl.CancelTouchEvent();
532   }
533   else if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_ACTIVATE_FAULTED_WIDGET ) == 0 )
534   {
535     impl.ActivateFaultedWidget();
536   }
537   else
538   {
539     ret = false;
540   }
541
542   return ret;
543 }
544
545 void WidgetView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
546 {
547   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( Dali::BaseHandle( object ) );
548
549   if( widgetView )
550   {
551     WidgetView& impl = GetImplementation( widgetView );
552
553     switch( index )
554     {
555       case Dali::WidgetView::WidgetView::Property::PREVIEW:
556       {
557         bool previewEnabled;
558         if( value.Get( previewEnabled ) )
559         {
560           impl.ShowPreview( previewEnabled );
561         }
562         break;
563       }
564       case Dali::WidgetView::WidgetView::Property::LOADING_TEXT:
565       {
566         bool textEnabled;
567         if( value.Get( textEnabled ) )
568         {
569           impl.ShowStateText( textEnabled );
570         }
571         break;
572       }
573       case Dali::WidgetView::WidgetView::Property::PERMANENT_DELETE:
574       {
575         bool del;
576         if( value.Get( del ) )
577         {
578           impl.SetPermanentDelete( del );
579         }
580         break;
581       }
582     }
583   }
584 }
585
586 Property::Value WidgetView::GetProperty( BaseObject* object, Property::Index index )
587 {
588   Property::Value value;
589   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( Dali::BaseHandle( object ) );
590
591   if( widgetView )
592   {
593     WidgetView& impl = GetImplementation( widgetView );
594
595     switch( index )
596     {
597       case Dali::WidgetView::WidgetView::Property::WIDGET_ID:
598       {
599         value = impl.GetWidgetId();
600         break;
601       }
602       case Dali::WidgetView::WidgetView::Property::INSTANCE_ID:
603       {
604         value = impl.GetInstanceId();
605         break;
606       }
607       case Dali::WidgetView::WidgetView::Property::CONTENT_INFO:
608       {
609         value = impl.GetContentInfo();
610         break;
611       }
612       case Dali::WidgetView::WidgetView::Property::TITLE:
613       {
614         value = impl.GetTitle();
615         break;
616       }
617       case Dali::WidgetView::WidgetView::Property::UPDATE_PERIOD:
618       {
619         value = impl.GetUpdatePeriod();
620         break;
621       }
622       case Dali::WidgetView::WidgetView::Property::PREVIEW:
623       {
624         value = impl.IsPreviewVisible();
625         break;
626       }
627       case Dali::WidgetView::WidgetView::Property::LOADING_TEXT:
628       {
629         value = impl.IsStateTextVisible();
630         break;
631       }
632       case Dali::WidgetView::WidgetView::Property::WIDGET_STATE_FAULTED:
633       {
634         value = impl.IsWidgetFaulted();
635         break;
636       }
637       case Dali::WidgetView::WidgetView::Property::PERMANENT_DELETE:
638       {
639         value = impl.IsPermanentDelete();
640         break;
641       }
642     }
643   }
644
645   return value;
646 }
647
648 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetAddedSignal()
649 {
650   return mWidgetAddedSignal;
651 }
652
653 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetDeletedSignal()
654 {
655   return mWidgetDeletedSignal;
656 }
657
658 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetCreationAbortedSignal()
659 {
660   return mWidgetCreationAbortedSignal;
661 }
662
663 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetContentUpdatedSignal()
664 {
665   return mWidgetContentUpdatedSignal;
666 }
667
668 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetUpdatePeriodChangedSignal()
669 {
670   return mWidgetUpdatePeriodChangedSignal;
671 }
672
673 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetFaultedSignal()
674 {
675   return mWidgetFaultedSignal;
676 }
677
678 void WidgetView::OnInitialize()
679 {
680   char* instanceId = NULL;
681   char* previewPath = NULL;
682   std::string previewImage;
683   widget_size_type_e sizeType;
684   screen_connector_toolkit_ops ops;
685
686   int ret = widget_instance_create( mWidgetId.c_str(), &instanceId );
687   if( ret < 0 || !instanceId )
688   {
689     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is failed [%s].\n", mWidgetId.c_str() );
690     return;
691   }
692
693   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is called. [widget id = %s, instance id = %s]\n",
694                  mWidgetId.c_str(), instanceId );
695
696   mInstanceId = instanceId;
697
698   // Preview image
699   widget_service_get_size_type( mWidth, mHeight, &sizeType );
700
701   previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
702   if( previewPath )
703   {
704     previewImage = previewPath;
705     free( previewPath );
706   }
707   else
708   {
709     previewImage = tzplatform_getenv( TZ_SYS_SHARE );
710     previewImage.append( WIDGET_VIEW_RESOURCE_DEFAULT_IMG );
711   }
712
713   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: preview image path = %s\n", previewImage.c_str() );
714
715   mPreviewImage = Toolkit::ImageView::New( previewImage );
716
717   mPreviewImage.SetParentOrigin( ParentOrigin::CENTER );
718   mPreviewImage.SetAnchorPoint( AnchorPoint::CENTER );
719
720   if( !previewPath )
721   {
722     mPreviewImage.SetSize( mWidth, mHeight );
723   }
724
725   Self().SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
726   Self().SetSize( mWidth, mHeight );
727
728   Self().Add( mPreviewImage );
729
730   // State text
731   // TODO: use po files
732   mStateText = Toolkit::TextLabel::New( "Loading..." );
733
734   mStateText.SetParentOrigin( ParentOrigin::CENTER );
735   mStateText.SetAnchorPoint( AnchorPoint::CENTER );
736   mStateText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
737   mStateText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
738
739   mPreviewImage.Add( mStateText );
740
741   // launch widget
742   mPid = widget_instance_launch( instanceId, (char *)mContentInfo.c_str(), mWidth, mHeight );
743   if( mPid < 0)
744   {
745     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
746
747     // Emit signal
748     Dali::WidgetView::WidgetView handle( GetOwner() );
749     mWidgetCreationAbortedSignal.Emit( handle );
750
751     return;
752   }
753
754   ops.updated_cb = OnBufferUpdated;
755   ops.removed_cb = OnSurfaceRemoved;
756   ops.added_cb = OnBufferAdded;
757   mWatcherHandle = screen_connector_toolkit_add(&ops, (char *)instanceId, SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET, this);
758   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
759
760 }
761
762 void WidgetView::OnStageConnection( int depth )
763 {
764   Control::OnStageConnection( depth );
765 }
766
767 void WidgetView::OnStageDisconnection()
768 {
769   Control::OnStageDisconnection();
770 }
771
772 void WidgetView::OnSizeSet( const Vector3& targetSize )
773 {
774   if( mWidgetImageView )
775   {
776     mWidgetImageView.SetSize( targetSize );
777   }
778 }
779
780 bool WidgetView::IsWidgetImageView()
781 {
782   return ( mWidgetImageView )? true: false;
783 }
784
785 void WidgetView::UpdateImageSource( tbm_surface_h source )
786 {
787   mImageSource->SetSource( source );
788   Dali::Stage::GetCurrent().KeepRendering( 0.0f );
789 }
790
791 void WidgetView::ConnectSignal( tizen_remote_surface* surface )
792 {
793   if( mWidgetImageView && surface )
794   {
795     mRemoteSurface = surface;
796
797     Self().TouchSignal().Connect( this, &WidgetView::OnTouch );
798     Self().WheelEventSignal().Connect( this, &WidgetView::OnWheelEvent );
799   }
800
801 }
802
803 bool WidgetView::OnTouch( Dali::Actor actor, const Dali::TouchData& event )
804 {
805   tizen_remote_surface_event_type type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_NONE;
806
807   if( event.GetPointCount() == 0 || mRemoteSurface == NULL )
808   {
809     return false;
810   }
811
812   switch( event.GetState( 0 ) )
813   {
814     case Dali::PointState::UP:
815     {
816       type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP;
817       break;
818     }
819     case Dali::PointState::DOWN:
820     {
821       type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN;
822       break;
823     }
824     case Dali::PointState::MOTION:
825     {
826       type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE;
827       break;
828     }
829     default:
830     {
831       return false;
832     }
833   }
834
835   int button = 1;
836
837   if( type == TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE )
838   {
839     button = 0 ;
840   }
841
842   Vector2 localPos = event.GetLocalPosition( 0 );
843
844   tizen_remote_surface_transfer_mouse_event( mRemoteSurface,
845                                              type,
846                                              0,
847                                              button,
848                                              (int)localPos.x,
849                                              (int)localPos.y,
850                                              wl_fixed_from_double( event.GetEllipseRadius( 0 ).x ),
851                                              wl_fixed_from_double( event.GetEllipseRadius( 0 ).y ),
852                                              wl_fixed_from_double( event.GetPressure( 0 ) ),
853                                              wl_fixed_from_double( event.GetAngle( 0 ).degree ),
854                                              TIZEN_INPUT_DEVICE_CLAS_TOUCHSCREEN,
855                                              TIZEN_INPUT_DEVICE_SUBCLAS_NONE,
856                                              "",
857                                              event.GetTime()
858                                            );
859   return true;
860 }
861
862 bool WidgetView::OnWheelEvent( Dali::Actor actor, const Dali::WheelEvent& event )
863 {
864   if( mRemoteSurface == NULL )
865   {
866     return false;
867   }
868   //ToDo: We should check TIZEN_INPUT_DEVICE_CLAS_MOUSE
869   tizen_remote_surface_transfer_mouse_wheel( mRemoteSurface,
870                                              event.direction,
871                                              event.z,
872                                              TIZEN_INPUT_DEVICE_CLAS_MOUSE,
873                                              TIZEN_INPUT_DEVICE_SUBCLAS_NONE,
874                                              "",
875                                              event.timeStamp
876                                            );
877   return true;
878 }
879
880 Vector3 WidgetView::GetNaturalSize()
881 {
882   Vector3 size;
883   size.x = mWidth;
884   size.y = mHeight;
885
886   if( size.x > 0 && size.y > 0 )
887   {
888     size.z = std::min( size.x, size.y );
889     return size;
890   }
891   else
892   {
893     return Control::GetNaturalSize();
894   }
895 }
896
897 float WidgetView::GetHeightForWidth( float width )
898 {
899   if( mWidth > 0 && mHeight > 0 )
900   {
901     return GetHeightForWidthBase( width );
902   }
903   else
904   {
905     return Control::GetHeightForWidthBase( width );
906   }
907 }
908
909 float WidgetView::GetWidthForHeight( float height )
910 {
911   if( mWidth > 0 && mHeight > 0 )
912   {
913     return GetWidthForHeightBase( height );
914   }
915   else
916   {
917     return Control::GetWidthForHeightBase( height );
918   }
919 }
920
921 void WidgetView::CloseRemoteSurface()
922 {
923   screen_connector_toolkit_remove( mWatcherHandle );
924   mRemoteSurface = NULL;
925 }
926
927 } // namespace Internal
928
929 } // namespace WidgetView
930
931 } // namespace Dali