3 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
9 * http://floralicense.org/license/
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.
19 #include <internal/widget_view/widget_view_impl.h>
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/integration-api/debug.h>
30 #include <Ecore_Input.h>
31 #include <widget_service.h>
32 #include <widget_instance.h>
33 #include <tzplatform_config.h>
34 #include <wayland-extension/tizen-extension-client-protocol.h>
35 #include <aul_rsm_viewer.h>
49 #define WIDGET_VIEW_RESOURCE_DEFAULT_IMG "/widget_viewer_dali/images/unknown.png"
51 #if defined(DEBUG_ENABLED)
52 Integration::Log::Filter* gWidgetViewLogging = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_WIDGET_VIEW" );
55 static Eina_Bool OnKeyDown( void* data, int type, void* eventInfo )
57 Ecore_Event_Key *event = static_cast< Ecore_Event_Key* >( eventInfo );
58 tizen_remote_surface* surface = static_cast< tizen_remote_surface* >( data );
60 tizen_remote_surface_transfer_key_event( surface,
61 TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_DOWN,
63 ecore_device_class_get(event->dev),
64 ecore_device_subclass_get(event->dev),
65 ecore_device_identifier_get(event->dev),
72 static Eina_Bool OnKeyUp(void* data, int type, void* eventInfo)
74 Ecore_Event_Key *event = static_cast< Ecore_Event_Key* >( eventInfo );
75 tizen_remote_surface* surface = static_cast< tizen_remote_surface* >( data );
77 tizen_remote_surface_transfer_key_event( surface,
78 TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_UP,
80 ecore_device_class_get(event->dev),
81 ecore_device_subclass_get(event->dev),
82 ecore_device_identifier_get(event->dev),
88 static void OnSurfaceUpdate( struct tizen_remote_surface* surface, wl_buffer* buffer, uint32_t time, void* data )
90 Dali::WidgetView::Internal::WidgetView* widgetView = static_cast< Dali::WidgetView::Internal::WidgetView* >( data );
92 if( widgetView && !widgetView->IsWidgetImageView() )
94 tizen_remote_surface_transfer_visibility( surface, TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE);
96 widgetView->CreateWidgetImageView();
97 widgetView->ConnectSignal( surface );
98 ecore_event_handler_add( ECORE_EVENT_KEY_DOWN, OnKeyDown, surface );
99 ecore_event_handler_add( ECORE_EVENT_KEY_UP, OnKeyUp, surface );
103 //get tbm surface from buffer
104 tbm_surface_h tbmSurface = static_cast< tbm_surface_h >( wl_buffer_get_user_data( buffer ) );
105 widgetView->UpdateImageSource( tbmSurface );
108 static void OnSurfaceMissing( struct tizen_remote_surface* surface, void* data )
110 //ToDo: WidgetDeletedSignal
114 static struct aul_rsm_handler_s remoteSurfaceHandler = {
119 } // unnamed namespace
121 Dali::WidgetView::WidgetView WidgetView::New( const std::string& widgetId, const std::string& contentInfo, int width, int height, double updatePeriod )
123 // Create the implementation, temporarily owned on stack
124 IntrusivePtr< WidgetView > internalWidgetView = new WidgetView( widgetId, contentInfo, width, height, updatePeriod );
126 // Pass ownership to CustomActor
127 Dali::WidgetView::WidgetView widgetView( *internalWidgetView );
129 // Second-phase init of the implementation
130 // This can only be done after the CustomActor connection has been made...
131 internalWidgetView->Initialize();
136 WidgetView::WidgetView()
137 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
146 mUpdatePeriod( 0.0 ),
147 mPreviewEnabled( true ),
148 mStateTextEnabled( true ),
149 mPermanentDelete( true )
153 WidgetView::WidgetView( const std::string& widgetId, const std::string& contentInfo, int width, int height, double updatePeriod )
154 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
155 mWidgetId( widgetId ),
157 mContentInfo( contentInfo ),
163 mUpdatePeriod( updatePeriod ),
164 mPreviewEnabled( true ),
165 mStateTextEnabled( true ),
166 mPermanentDelete( true )
170 WidgetView::~WidgetView()
172 if( !mWidgetId.empty() && !mInstanceId.empty() )
174 widget_instance_terminate( mInstanceId.c_str() );
176 if( mPermanentDelete )
178 widget_instance_destroy( mInstanceId.c_str() );
184 bundle_free( mBundle );
188 bool WidgetView::PauseWidget()
190 int ret = widget_instance_pause( mInstanceId.c_str() );
193 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Fail to pause widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
197 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Widget is paused (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
202 bool WidgetView::ResumeWidget()
204 int ret = widget_instance_resume( mInstanceId.c_str() );
207 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Fail to resume widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
211 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Widget is resumed (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
216 const std::string& WidgetView::GetWidgetId() const
221 const std::string& WidgetView::GetInstanceId() const
226 const std::string& WidgetView::GetContentInfo()
228 widget_instance_h instance;
229 char* contentInfo = NULL;
231 mContentInfo.clear();
233 if( mWidgetId.empty() || mInstanceId.empty() )
235 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Widget id (%s) or instance id (%s) is invalid.\n", mWidgetId.c_str(), mInstanceId.c_str() );
239 instance = widget_instance_get_instance( mWidgetId.c_str(), mInstanceId.c_str() );
242 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: widget_instance_get_instance is failed. [%s]\n", mInstanceId.c_str() );
246 if( widget_instance_get_content( instance, &contentInfo ) < 0 )
248 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Failed to get content of widget. [%s]\n", mInstanceId.c_str() );
252 mContentInfo = reinterpret_cast< char* >( contentInfo );
257 const std::string& WidgetView::GetTitle()
259 //ToDo: We should add some codes by considering widget_viewer_evas
262 mTitle = widget_service_get_name( mWidgetId.c_str(), NULL );
265 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetTitle: title = %s\n", mTitle.c_str() );
270 double WidgetView::GetUpdatePeriod() const
272 return mUpdatePeriod;
275 void WidgetView::Show()
277 if( mWidgetImageView )
279 mWidgetImageView.SetVisible( true );
283 void WidgetView::Hide()
285 if( mWidgetImageView )
287 mWidgetImageView.SetVisible( false );
291 bool WidgetView::CancelTouchEvent()
295 tizen_remote_surface_transfer_touch_cancel( mRemoteSurface );
302 void WidgetView::SetPreviewEnabled( bool enabled )
304 mPreviewEnabled = enabled;
308 mPreviewImage.SetVisible( enabled );
312 bool WidgetView::GetPreviewEnabled() const
314 return mPreviewEnabled;
317 void WidgetView::SetStateTextEnabled( bool enabled )
319 mStateTextEnabled = enabled;
323 mStateText.SetVisible( enabled );
327 bool WidgetView::GetStateTextEnabled() const
329 return mStateTextEnabled;
332 void WidgetView::ActivateFaultedWidget()
336 // Esable preview and text
337 if( mPreviewEnabled )
339 mPreviewImage.SetVisible( true );
342 if( mStateTextEnabled )
344 mStateText.SetVisible( true );
347 // launch widget again
348 mPid = widget_instance_launch( mInstanceId.c_str(), (char *)mContentInfo.c_str(), mWidth, mHeight );
351 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
354 Dali::WidgetView::WidgetView handle( GetOwner() );
355 mWidgetCreationAbortedSignal.Emit( handle );
360 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
364 bool WidgetView::IsWidgetFaulted()
366 return mPid < 0 ? true : false;
369 void WidgetView::SetPermanentDelete( bool permanentDelete )
371 mPermanentDelete = permanentDelete;
374 void WidgetView::CreateWidgetImageView()
377 mImageSource = Dali::NativeImageSource::New( source );
378 Dali::NativeImage image = Dali::NativeImage::New( *mImageSource );
380 mWidgetImageView = Dali::Toolkit::ImageView::New( image );
382 mWidgetImageView.SetParentOrigin( ParentOrigin::CENTER );
383 mWidgetImageView.SetAnchorPoint( AnchorPoint::CENTER );
384 mWidgetImageView.SetSize( mWidth, mHeight );
386 Self().Add( mWidgetImageView );
388 // Disable preview and text
389 if( mPreviewEnabled )
391 mPreviewImage.SetVisible( false );
394 if( mStateTextEnabled )
396 mStateText.SetVisible( false );
400 Dali::WidgetView::WidgetView handle( GetOwner() );
401 mWidgetAddedSignal.Emit( handle );
403 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::AddObjectView: ObjectView is added.\n" );
406 void WidgetView::RemoveObjectView()
408 // Enable preview and text
409 if( mPreviewEnabled )
411 mPreviewImage.SetVisible( true );
414 if( mStateTextEnabled )
416 mStateText.SetVisible( true );
420 Dali::WidgetView::WidgetView handle( GetOwner() );
421 mWidgetDeletedSignal.Emit( handle );
423 mWidgetImageView.Reset();
425 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::RemoveObjectView: ObjectView is removed.\n" );
428 void WidgetView::SendWidgetEvent( int event )
430 Dali::WidgetView::WidgetView handle( GetOwner() );
432 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::SendWidgetEvent: event = %d widget = %s\n", event, mWidgetId.c_str() );
437 case WIDGET_INSTANCE_EVENT_UPDATE:
439 mWidgetContentUpdatedSignal.Emit( handle );
442 case WIDGET_INSTANCE_EVENT_PERIOD_CHANGED:
444 mWidgetUpdatePeriodChangedSignal.Emit( handle );
447 case WIDGET_INSTANCE_EVENT_SIZE_CHANGED:
449 mWidgetResizedSignal.Emit( handle );
452 case WIDGET_INSTANCE_EVENT_EXTRA_UPDATED:
454 mWidgetExtraInfoUpdatedSignal.Emit( handle );
457 case WIDGET_INSTANCE_EVENT_FAULT:
459 mWidgetFaultedSignal.Emit( handle );
469 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetAddedSignal()
471 return mWidgetAddedSignal;
474 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetDeletedSignal()
476 return mWidgetDeletedSignal;
479 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetCreationAbortedSignal()
481 return mWidgetCreationAbortedSignal;
484 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetResizedSignal()
486 return mWidgetResizedSignal;
489 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetContentUpdatedSignal()
491 return mWidgetContentUpdatedSignal;
494 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetExtraInfoUpdatedSignal()
496 return mWidgetExtraInfoUpdatedSignal;
499 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetUpdatePeriodChangedSignal()
501 return mWidgetUpdatePeriodChangedSignal;
504 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetFaultedSignal()
506 return mWidgetFaultedSignal;
509 void WidgetView::OnInitialize()
511 char* instanceId = NULL;
512 char* previewPath = NULL;
513 std::string previewImage;
514 widget_size_type_e sizeType;
516 int ret = widget_instance_create( mWidgetId.c_str(), &instanceId );
517 if( ret < 0 || !instanceId )
519 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is failed [%s].\n", mWidgetId.c_str() );
523 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is called. [widget id = %s, instance id = %s]\n",
524 mWidgetId.c_str(), instanceId );
526 mInstanceId = instanceId;
529 widget_service_get_size_type( mWidth, mHeight, &sizeType );
531 previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
534 previewImage = previewPath;
539 previewImage = tzplatform_getenv( TZ_SYS_SHARE );
540 previewImage.append( WIDGET_VIEW_RESOURCE_DEFAULT_IMG );
543 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: preview image path = %s\n", previewImage.c_str() );
545 mPreviewImage = Toolkit::ImageView::New( previewImage );
547 mPreviewImage.SetParentOrigin( ParentOrigin::CENTER );
548 mPreviewImage.SetAnchorPoint( AnchorPoint::CENTER );
552 mPreviewImage.SetSize( mWidth, mHeight );
555 Self().SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
556 Self().Add( mPreviewImage );
559 // TODO: use po files
560 mStateText = Toolkit::TextLabel::New( "Loading..." );
562 mStateText.SetParentOrigin( ParentOrigin::CENTER );
563 mStateText.SetAnchorPoint( AnchorPoint::CENTER );
564 mStateText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
565 mStateText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
567 mPreviewImage.Add( mStateText );
570 mPid = widget_instance_launch( instanceId, (char *)mContentInfo.c_str(), mWidth, mHeight );
573 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
576 Dali::WidgetView::WidgetView handle( GetOwner() );
577 mWidgetCreationAbortedSignal.Emit( handle );
582 aul_rsm_viewer_set_surface_handler( mInstanceId.c_str(), &remoteSurfaceHandler, this );
584 DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
588 void WidgetView::OnSizeSet( const Vector3& targetSize )
590 if( mWidgetImageView )
592 mWidgetImageView.SetSize( targetSize );
596 bool WidgetView::IsWidgetImageView()
598 return ( mWidgetImageView )? true: false;
601 void WidgetView::UpdateImageSource( tbm_surface_h source )
603 mImageSource->SetSource( source );
604 Dali::Stage::GetCurrent().KeepRendering( 0.0f );
607 void WidgetView::ConnectSignal( tizen_remote_surface* surface )
609 if( mWidgetImageView )
611 mRemoteSurface = surface;
612 mWidgetImageView.TouchSignal().Connect( this, &WidgetView::OnTouch );
613 mWidgetImageView.WheelEventSignal().Connect( this, &WidgetView::OnWheelEvent );
618 bool WidgetView::OnTouch( Dali::Actor actor, const Dali::TouchData& event )
620 tizen_remote_surface_event_type type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_NONE;
622 switch( event.GetState( 0 ) )
624 case Dali::PointState::UP:
626 type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP;
629 case Dali::PointState::DOWN:
631 type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN;
634 case Dali::PointState::MOTION:
636 type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE;
645 tizen_remote_surface_transfer_mouse_event( mRemoteSurface,
647 event.GetDeviceId( 0 ),
649 event.GetLocalPosition( 0 ).x,
650 event.GetLocalPosition( 0 ).y,
651 event.GetEllipseRadius( 0 ).x,
652 event.GetEllipseRadius( 0 ).y,
653 event.GetPressure( 0 ),
654 event.GetAngle( 0 ).degree,
655 TIZEN_INPUT_DEVICE_CLAS_MOUSE,
656 TIZEN_INPUT_DEVICE_SUBCLAS_NONE,
663 bool WidgetView::OnWheelEvent( Dali::Actor actor, const Dali::WheelEvent& event )
665 tizen_remote_surface_transfer_mouse_wheel( mRemoteSurface,
668 TIZEN_INPUT_DEVICE_CLAS_MOUSE,
669 TIZEN_INPUT_DEVICE_SUBCLAS_NONE,
676 } // namespace Internal
678 } // namespace WidgetView