[widget-viewer-dali] Change the license as Flora
[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/integration-api/debug.h>
25 #include <string.h>
26 #include <widget_service.h>
27 #include <widget_instance.h>
28 #include <tzplatform_config.h>
29
30 namespace Dali
31 {
32
33 namespace WidgetView
34 {
35
36 namespace Internal
37 {
38
39 namespace
40 {
41
42 #define WIDGET_VIEW_RESOURCE_DEFAULT_IMG "/widget_viewer_dali/images/unknown.png"
43
44 #if defined(DEBUG_ENABLED)
45 Integration::Log::Filter* gWidgetViewLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_WIDGET_VIEW" );
46 #endif
47
48 } // unnamed namespace
49
50 Dali::WidgetView::WidgetView WidgetView::New( const std::string& widgetId, const std::string& contentInfo, int width, int height, double updatePeriod )
51 {
52   // Create the implementation, temporarily owned on stack
53   IntrusivePtr< WidgetView > internalWidgetView = new WidgetView( widgetId, contentInfo, width, height, updatePeriod );
54
55   // Pass ownership to CustomActor
56   Dali::WidgetView::WidgetView widgetView( *internalWidgetView );
57
58   // Second-phase init of the implementation
59   // This can only be done after the CustomActor connection has been made...
60   internalWidgetView->Initialize();
61
62   return widgetView;
63 }
64
65 WidgetView::WidgetView()
66 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
67   mWidgetId(),
68   mInstanceId(),
69   mContentInfo(),
70   mTitle(),
71   mBundle( NULL ),
72   mWidth( 0 ),
73   mHeight( 0 ),
74   mPid( 0 ),
75   mUpdatePeriod( 0.0 ),
76   mPreviewEnabled( true ),
77   mStateTextEnabled( true ),
78   mPermanentDelete( true )
79 {
80 }
81
82 WidgetView::WidgetView( const std::string& widgetId, const std::string& contentInfo, int width, int height, double updatePeriod )
83 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
84   mWidgetId( widgetId ),
85   mInstanceId(),
86   mContentInfo( contentInfo ),
87   mTitle(),
88   mBundle( NULL ),
89   mWidth( width ),
90   mHeight( height ),
91   mPid( 0 ),
92   mUpdatePeriod( updatePeriod ),
93   mPreviewEnabled( true ),
94   mStateTextEnabled( true ),
95   mPermanentDelete( true )
96 {
97 }
98
99 WidgetView::~WidgetView()
100 {
101   if( !mWidgetId.empty() && !mInstanceId.empty() )
102   {
103     widget_instance_terminate( mWidgetId.c_str(), mInstanceId.c_str() );
104
105     if( mPermanentDelete )
106     {
107       widget_instance_destroy( mWidgetId.c_str(), mInstanceId.c_str() );
108     }
109   }
110
111   if( mBundle )
112   {
113     bundle_free( mBundle );
114   }
115 }
116
117 bool WidgetView::PauseWidget()
118 {
119   int ret = widget_instance_pause( mWidgetId.c_str(), mInstanceId.c_str() );
120   if( ret < 0 )
121   {
122     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Fail to pause widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
123     return false;
124   }
125
126   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Widget is paused (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
127
128   return true;
129 }
130
131 bool WidgetView::ResumeWidget()
132 {
133   int ret = widget_instance_resume( mWidgetId.c_str(), mInstanceId.c_str() );
134   if( ret < 0 )
135   {
136     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Fail to resume widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
137     return false;
138   }
139
140   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Widget is resumed (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
141
142   return true;
143 }
144
145 const std::string& WidgetView::GetWidgetId() const
146 {
147   return mWidgetId;
148 }
149
150 const std::string& WidgetView::GetInstanceId() const
151 {
152   return mInstanceId;
153 }
154
155 const std::string& WidgetView::GetContentInfo()
156 {
157   widget_instance_h instance;
158   bundle* bundle = NULL;
159   bundle_raw* contentInfo = NULL;
160   int contentLength = 0;
161
162   mContentInfo.clear();
163
164   if( mWidgetId.empty() || mInstanceId.empty() )
165   {
166     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Widget id (%s) or instance id (%s) is invalid.\n", mWidgetId.c_str(), mInstanceId.c_str() );
167     return mContentInfo;
168   }
169
170   instance = widget_instance_get_instance( mWidgetId.c_str(), mInstanceId.c_str() );
171   if( !instance )
172   {
173     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: widget_instance_get_instance is failed. [%s]\n", mInstanceId.c_str() );
174     return mContentInfo;
175   }
176
177   if( widget_instance_get_content( instance, &bundle ) < 0 )
178   {
179     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Failed to get content of widget. [%s]\n", mInstanceId.c_str() );
180     return mContentInfo;
181   }
182
183   if( !bundle )
184   {
185     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Cotent of widget [%s] is invalid.\n", mInstanceId.c_str() );
186     return mContentInfo;
187   }
188
189   if( bundle_encode( bundle, &contentInfo, &contentLength ) < 0 )
190   {
191     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: bundle_encode is failed. [%s]\n", mInstanceId.c_str() );
192     return mContentInfo;
193   }
194
195   mContentInfo = reinterpret_cast< char* >( contentInfo );
196
197   return mContentInfo;
198 }
199
200 const std::string& WidgetView::GetTitle()
201 {
202   if( mObjectView )
203   {
204     mTitle = mObjectView.GetTitle();
205     if( mTitle.empty() )
206     {
207       mTitle = widget_service_get_name( mWidgetId.c_str(), NULL );
208     }
209   }
210
211   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetTitle: title = %s\n", mTitle.c_str() );
212
213   return mTitle;
214 }
215
216 double WidgetView::GetUpdatePeriod() const
217 {
218   return mUpdatePeriod;
219 }
220
221 void WidgetView::Show()
222 {
223   if( mObjectView )
224   {
225     mObjectView.Show();
226   }
227 }
228
229 void WidgetView::Hide()
230 {
231   if( mObjectView )
232   {
233     mObjectView.Hide();
234   }
235 }
236
237 bool WidgetView::CancelTouchEvent()
238 {
239   if( mObjectView )
240   {
241     return mObjectView.CancelTouchEvent();
242   }
243
244   return false;
245 }
246
247 void WidgetView::SetPreviewEnabled( bool enabled )
248 {
249   mPreviewEnabled = enabled;
250
251   if( mPreviewImage )
252   {
253     mPreviewImage.SetVisible( enabled );
254   }
255 }
256
257 bool WidgetView::GetPreviewEnabled() const
258 {
259   return mPreviewEnabled;
260 }
261
262 void WidgetView::SetStateTextEnabled( bool enabled )
263 {
264   mStateTextEnabled = enabled;
265
266   if( mStateText )
267   {
268     mStateText.SetVisible( enabled );
269   }
270 }
271
272 bool WidgetView::GetStateTextEnabled() const
273 {
274   return mStateTextEnabled;
275 }
276
277 void WidgetView::ActivateFaultedWidget()
278 {
279   if( mPid < 0 )
280   {
281     // Esable preview and text
282     if( mPreviewEnabled )
283     {
284       mPreviewImage.SetVisible( true );
285     }
286
287     if( mStateTextEnabled )
288     {
289       mStateText.SetVisible( true );
290     }
291
292     // launch widget again
293     mPid = widget_instance_launch( mWidgetId.c_str(), mInstanceId.c_str(), mBundle, mWidth, mHeight );
294     if( mPid < 0)
295     {
296       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
297
298       // Emit signal
299       Dali::WidgetView::WidgetView handle( GetOwner() );
300       mWidgetCreationAbortedSignal.Emit( handle );
301
302       return;
303     }
304
305     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
306   }
307 }
308
309 bool WidgetView::IsWidgetFaulted()
310 {
311   return mPid < 0 ? true : false;
312 }
313
314 void WidgetView::SetPermanentDelete( bool permanentDelete )
315 {
316   mPermanentDelete = permanentDelete;
317 }
318
319 void WidgetView::AddObjectView( Pepper::ObjectView objectView )
320 {
321   mObjectView = objectView;
322
323   mObjectView.SetParentOrigin( ParentOrigin::CENTER );
324   mObjectView.SetAnchorPoint( AnchorPoint::CENTER );
325
326   Self().Add( mObjectView );
327
328   // Disable preview and text
329   if( mPreviewEnabled )
330   {
331     mPreviewImage.SetVisible( false );
332   }
333
334   if( mStateTextEnabled )
335   {
336     mStateText.SetVisible( false );
337   }
338
339   // Emit signal
340   Dali::WidgetView::WidgetView handle( GetOwner() );
341   mWidgetAddedSignal.Emit( handle );
342
343   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::AddObjectView: ObjectView is added.\n" );
344 }
345
346 void WidgetView::RemoveObjectView()
347 {
348   // Enable preview and text
349   if( mPreviewEnabled )
350   {
351     mPreviewImage.SetVisible( true );
352   }
353
354   if( mStateTextEnabled )
355   {
356     mStateText.SetVisible( true );
357   }
358
359   // Emit signal
360   Dali::WidgetView::WidgetView handle( GetOwner() );
361   mWidgetDeletedSignal.Emit( handle );
362
363   mObjectView.Reset();
364
365   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::RemoveObjectView: ObjectView is removed.\n" );
366 }
367
368 void WidgetView::SendWidgetEvent( int event )
369 {
370   Dali::WidgetView::WidgetView handle( GetOwner() );
371
372   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::SendWidgetEvent: event = %d widget = %s\n", event,  mWidgetId.c_str() );
373
374   // Emit signal
375   switch( event )
376   {
377     case WIDGET_INSTANCE_EVENT_UPDATE:
378     {
379       mWidgetContentUpdatedSignal.Emit( handle );
380       break;
381     }
382     case WIDGET_INSTANCE_EVENT_PERIOD_CHANGED:
383     {
384       mWidgetUpdatePeriodChangedSignal.Emit( handle );
385       break;
386     }
387     case WIDGET_INSTANCE_EVENT_SIZE_CHANGED:
388     {
389       mWidgetResizedSignal.Emit( handle );
390       break;
391     }
392     case WIDGET_INSTANCE_EVENT_EXTRA_UPDATED:
393     {
394       mWidgetExtraInfoUpdatedSignal.Emit( handle );
395       break;
396     }
397     case WIDGET_INSTANCE_EVENT_FAULT:
398     {
399       mWidgetFaultedSignal.Emit( handle );
400       break;
401     }
402     default:
403     {
404       break;
405     }
406   }
407 }
408
409 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetAddedSignal()
410 {
411   return mWidgetAddedSignal;
412 }
413
414 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetDeletedSignal()
415 {
416   return mWidgetDeletedSignal;
417 }
418
419 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetCreationAbortedSignal()
420 {
421   return mWidgetCreationAbortedSignal;
422 }
423
424 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetResizedSignal()
425 {
426   return mWidgetResizedSignal;
427 }
428
429 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetContentUpdatedSignal()
430 {
431   return mWidgetContentUpdatedSignal;
432 }
433
434 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetExtraInfoUpdatedSignal()
435 {
436   return mWidgetExtraInfoUpdatedSignal;
437 }
438
439 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetUpdatePeriodChangedSignal()
440 {
441   return mWidgetUpdatePeriodChangedSignal;
442 }
443
444 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetFaultedSignal()
445 {
446   return mWidgetFaultedSignal;
447 }
448
449 void WidgetView::OnInitialize()
450 {
451   char* instanceId = NULL;
452   char* previewPath = NULL;
453   std::string previewImage;
454   widget_size_type_e sizeType;
455
456   if( !mContentInfo.empty() )
457   {
458     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: decode bundle\n" );
459
460     mBundle = bundle_decode( reinterpret_cast< const bundle_raw* >( mContentInfo.c_str() ), mContentInfo.length() );
461     if( !mBundle )
462     {
463       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: Invalid bundle data.\n" );
464       return;
465     }
466
467     bundle_get_str( mBundle, WIDGET_K_INSTANCE, &instanceId );
468   }
469
470   if( !instanceId )
471   {
472     int ret = widget_instance_create( mWidgetId.c_str(), &instanceId );
473     if( ret < 0 || !instanceId )
474     {
475       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is failed [%s].\n", mWidgetId.c_str() );
476       return;
477     }
478
479     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is called. [widget id = %s, instance id = %s]\n",
480                    mWidgetId.c_str(), instanceId );
481   }
482
483   mInstanceId = instanceId;
484
485   // Preview image
486   widget_service_get_size_type( mWidth, mHeight, &sizeType );
487
488   previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
489   if( previewPath )
490   {
491     previewImage = previewPath;
492     free( previewPath );
493   }
494   else
495   {
496     previewImage = tzplatform_getenv( TZ_SYS_SHARE );
497     previewImage.append( WIDGET_VIEW_RESOURCE_DEFAULT_IMG );
498   }
499
500   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: preview image path = %s\n", previewImage.c_str() );
501
502   mPreviewImage = Toolkit::ImageView::New( previewImage );
503
504   mPreviewImage.SetParentOrigin( ParentOrigin::CENTER );
505   mPreviewImage.SetAnchorPoint( AnchorPoint::CENTER );
506
507   if( !previewPath )
508   {
509     mPreviewImage.SetSize( mWidth, mHeight );
510   }
511
512   Self().SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
513   Self().Add( mPreviewImage );
514
515   // State text
516   // TODO: use po files
517   mStateText = Toolkit::TextLabel::New( "Loading..." );
518
519   mStateText.SetParentOrigin( ParentOrigin::CENTER );
520   mStateText.SetAnchorPoint( AnchorPoint::CENTER );
521   mStateText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
522   mStateText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
523
524   mPreviewImage.Add( mStateText );
525
526   // launch widget
527   mPid = widget_instance_launch( mWidgetId.c_str(), instanceId, mBundle, mWidth, mHeight );
528   if( mPid < 0)
529   {
530     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
531
532     // Emit signal
533     Dali::WidgetView::WidgetView handle( GetOwner() );
534     mWidgetCreationAbortedSignal.Emit( handle );
535
536     return;
537   }
538
539   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
540 }
541
542 void WidgetView::OnSizeSet( const Vector3& targetSize )
543 {
544   if( mObjectView )
545   {
546     mObjectView.SetSize( targetSize );
547   }
548 }
549
550 } // namespace Internal
551
552 } // namespace WidgetView
553
554 } // namespace Dali