[widget-viewer-dali]
[platform/core/uifw/widget-viewer-dali.git] / internal / widget_view / widget_view_impl.cpp
1 /*
2  * Copyright (c) 2016 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 // 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 period )
51 {
52   // Create the implementation, temporarily owned on stack
53   IntrusivePtr< WidgetView > internalWidgetView = new WidgetView( widgetId, contentInfo, width, height, period );
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   mPeriod( 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 period )
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   mPeriod( period ),
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 const std::string& WidgetView::GetWidgetId() const
118 {
119   return mWidgetId;
120 }
121
122 const std::string& WidgetView::GetInstanceId() const
123 {
124   return mInstanceId;
125 }
126
127 const std::string& WidgetView::GetContentInfo()
128 {
129   widget_instance_h instance;
130   bundle* bundle = NULL;
131   bundle_raw* contentInfo = NULL;
132   int contentLength = 0;
133
134   mContentInfo.clear();
135
136   if( mWidgetId.empty() || mInstanceId.empty() )
137   {
138     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Widget id (%s) or instance id (%s) is invalid.\n", mWidgetId.c_str(), mInstanceId.c_str() );
139     return mContentInfo;
140   }
141
142   instance = widget_instance_get_instance( mWidgetId.c_str(), mInstanceId.c_str() );
143   if( !instance )
144   {
145     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: widget_instance_get_instance is failed. [%s]\n", mInstanceId.c_str() );
146     return mContentInfo;
147   }
148
149   if( widget_instance_get_content( instance, &bundle ) < 0 )
150   {
151     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Failed to get content of widget. [%s]\n", mInstanceId.c_str() );
152     return mContentInfo;
153   }
154
155   if( !bundle )
156   {
157     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Cotent of widget [%s] is invalid.\n", mInstanceId.c_str() );
158     return mContentInfo;
159   }
160
161   if( bundle_encode( bundle, &contentInfo, &contentLength ) < 0 )
162   {
163     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: bundle_encode is failed. [%s]\n", mInstanceId.c_str() );
164     return mContentInfo;
165   }
166
167   mContentInfo = reinterpret_cast< char* >( contentInfo );
168
169   return mContentInfo;
170 }
171
172 const std::string& WidgetView::GetTitle()
173 {
174   if( mObjectView )
175   {
176     mTitle = mObjectView.GetTitle();
177     if( mTitle.empty() )
178     {
179       mTitle = widget_service_get_name( mWidgetId.c_str(), NULL );
180     }
181   }
182
183   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetTitle: title = %s\n", mTitle.c_str() );
184
185   return mTitle;
186 }
187
188 double WidgetView::GetPeriod() const
189 {
190   return mPeriod;
191 }
192
193 void WidgetView::SetPreviewEnabled( bool enabled )
194 {
195   mPreviewEnabled = enabled;
196
197   if( mPreviewImage )
198   {
199     mPreviewImage.SetVisible( enabled );
200   }
201 }
202
203 bool WidgetView::GetPreviewEnabled() const
204 {
205   return mPreviewEnabled;
206 }
207
208 void WidgetView::SetStateTextEnabled( bool enabled )
209 {
210   mStateTextEnabled = enabled;
211
212   if( mStateText )
213   {
214     mStateText.SetVisible( enabled );
215   }
216 }
217
218 bool WidgetView::GetStateTextEnabled() const
219 {
220   return mStateTextEnabled;
221 }
222
223 void WidgetView::ActivateFaultedWidget()
224 {
225   if( mPid < 0 )
226   {
227     // Esable preview and text
228     if( mPreviewEnabled )
229     {
230       mPreviewImage.SetVisible( true );
231     }
232
233     if( mStateTextEnabled )
234     {
235       mStateText.SetVisible( true );
236     }
237
238     // launch widget again
239     mPid = widget_instance_launch( mWidgetId.c_str(), mInstanceId.c_str(), mBundle, mWidth, mHeight );
240     if( mPid < 0)
241     {
242       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
243       return;
244     }
245
246     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
247   }
248 }
249
250 bool WidgetView::IsWidgetFaulted()
251 {
252   return mPid < 0 ? true : false;
253 }
254
255 void WidgetView::SetPermanentDelete( bool permanentDelete )
256 {
257   mPermanentDelete = permanentDelete;
258 }
259
260 void WidgetView::AddObjectView( Pepper::ObjectView objectView )
261 {
262   mObjectView = objectView;
263
264   mObjectView.SetParentOrigin( ParentOrigin::CENTER );
265   mObjectView.SetAnchorPoint( AnchorPoint::CENTER );
266
267   Self().Add( mObjectView );
268
269   // Disable preview and text
270   if( mPreviewEnabled )
271   {
272     mPreviewImage.SetVisible( false );
273   }
274
275   if( mStateTextEnabled )
276   {
277     mStateText.SetVisible( false );
278   }
279
280   // Emit signal
281   Dali::WidgetView::WidgetView handle( GetOwner() );
282   mWidgetAddedSignal.Emit( handle );
283 }
284
285 void WidgetView::RemoveObjectView()
286 {
287   // Emit signal
288   Dali::WidgetView::WidgetView handle( GetOwner() );
289   mWidgetDeletedSignal.Emit( handle );
290
291   mObjectView.Reset();
292 }
293
294 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetAddedSignal()
295 {
296   return mWidgetAddedSignal;
297 }
298
299 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetDeletedSignal()
300 {
301   return mWidgetDeletedSignal;
302 }
303
304 void WidgetView::OnInitialize()
305 {
306   char* instanceId = NULL;
307   char* previewPath = NULL;
308   std::string previewImage;
309   widget_size_type_e sizeType;
310
311   if( !mContentInfo.empty() )
312   {
313     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: decode bundle\n" );
314
315     mBundle = bundle_decode( reinterpret_cast< const bundle_raw* >( mContentInfo.c_str() ), mContentInfo.length() );
316     if( !mBundle )
317     {
318       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: Invalid bundle data.\n" );
319       return;
320     }
321
322     bundle_get_str( mBundle, WIDGET_K_INSTANCE, &instanceId );
323   }
324
325   if( !instanceId )
326   {
327     int ret = widget_instance_create( mWidgetId.c_str(), &instanceId );
328     if( ret < 0 || !instanceId )
329     {
330       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is failed [%s].\n", mWidgetId.c_str() );
331       return;
332     }
333
334     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is called. [widget id = %s, instance id = %s]\n",
335                    mWidgetId.c_str(), instanceId );
336   }
337
338   mInstanceId = instanceId;
339
340   // Preview image
341   widget_service_get_size_type( mWidth, mHeight, &sizeType );
342
343   previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
344   if( previewPath )
345   {
346     previewImage = previewPath;
347     free( previewPath );
348   }
349   else
350   {
351     previewImage = tzplatform_getenv( TZ_SYS_SHARE );
352     previewImage.append( WIDGET_VIEW_RESOURCE_DEFAULT_IMG );
353   }
354
355   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: preview image path = %s\n", previewImage.c_str() );
356
357   mPreviewImage = Toolkit::ImageView::New( previewImage );
358
359   mPreviewImage.SetParentOrigin( ParentOrigin::CENTER );
360   mPreviewImage.SetAnchorPoint( AnchorPoint::CENTER );
361
362   if( !previewPath )
363   {
364     mPreviewImage.SetSize( mWidth, mHeight );
365   }
366
367   Self().SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
368   Self().Add( mPreviewImage );
369
370   // State text
371   // TODO: use po files
372   mStateText = Toolkit::TextLabel::New( "Loading..." );
373
374   mStateText.SetParentOrigin( ParentOrigin::CENTER );
375   mStateText.SetAnchorPoint( AnchorPoint::CENTER );
376   mStateText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
377   mStateText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
378
379   mPreviewImage.Add( mStateText );
380
381   // launch widget
382   mPid = widget_instance_launch( mWidgetId.c_str(), instanceId, mBundle, mWidth, mHeight );
383   if( mPid < 0)
384   {
385     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
386     return;
387   }
388
389   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
390 }
391
392 } // namespace Internal
393
394 } // namespace WidgetView
395
396 } // namespace Dali