[Tizen] Add DALi Autofill implementation
[platform/core/uifw/dali-adaptor.git] / dali / internal / input / tizen-wayland / autofill-manager-impl-ecore-wl.cpp
1 /*
2  * Copyright (c) 2019 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 <dali/internal/input/tizen-wayland/autofill-manager-impl-ecore-wl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/integration-api/debug.h>
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/adaptor/common/adaptor-impl.h>
27 #include <dali/internal/system/common/singleton-service-impl.h>
28
29
30 namespace Dali
31 {
32
33 namespace Internal
34 {
35
36 namespace Adaptor
37 {
38
39 namespace
40 {
41 #if defined(DEBUG_ENABLED)
42 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_AUTOFILL");
43 #endif
44
45 // Signals
46 const char* const SIGNAL_AUTHENTICATION_RECEIVED = "authenticationReceived";
47 const char* const SIGNAL_FILL_RESPONSE_RECEIVED = "fillResponseReceived";
48 const char* const SIGNAL_LIST_RECEIVED = "listReceived";
49
50
51 #ifdef CAPI_AUTOFILL_SUPPORT
52
53 // All methods in this range are Static function calls used by ecore 'c' style callback registration
54 static void ConnectionStatusChangedCallback( autofill_h autofillHandle, autofill_connection_status_e status, void *user_data )
55 {
56   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::ConnectionStatusChangedCallback mAutofillHandle : %p \n", autofillHandle );
57
58   switch( status )
59   {
60     case AUTOFILL_CONNECTION_STATUS_CONNECTED:
61     {
62       DALI_LOG_INFO( gLogFilter, Debug::General, "Autofill Connected.\n" );
63       break;
64     }
65     case AUTOFILL_CONNECTION_STATUS_DISCONNECTED:
66     {
67       DALI_LOG_INFO( gLogFilter, Debug::General, "Autofill Disconnected.\n" );
68       break;
69     }
70     case AUTOFILL_CONNECTION_STATUS_REJECTED:
71     {
72       DALI_LOG_INFO( gLogFilter, Debug::General, "Autofill Rejected.\n" );
73       break;
74     }
75     default:
76     {
77       // Do nothing
78       break;
79     }
80   }
81 }
82
83 // Callback to receive the authentication information.
84 static void AuthInfoCallback( autofill_h ah, autofill_auth_info_h authInfoHandle, void *data )
85 {
86   Dali::AutofillManager autofill = AutofillManager::Get();
87   Internal::Adaptor::AutofillManager& autofillImpl = Internal::Adaptor::GetImplementation( autofill );
88   Internal::Adaptor::AutofillManagerEcoreWl& autofillImplWl = static_cast<Internal::Adaptor::AutofillManagerEcoreWl&>( autofillImpl );
89   autofillImplWl.ReceiveAuthInfo( authInfoHandle, data );
90 }
91
92 // If there's an only one fill response group, then this callback is called.
93 static bool FillResponseItemCallback( autofill_fill_response_item_h itemHandle, void *userData )
94 {
95   Dali::AutofillManager autofill = AutofillManager::Get();
96   Internal::Adaptor::AutofillManager& autofillImpl = Internal::Adaptor::GetImplementation( autofill );
97   Internal::Adaptor::AutofillManagerEcoreWl& autofillImplWl = static_cast<Internal::Adaptor::AutofillManagerEcoreWl&>( autofillImpl );
98   autofillImplWl.FillGroupItem( itemHandle, userData ); // Implementation here
99   return true;
100 }
101
102 // If the fill response groups are multiple, then this callback is called.
103 static bool FillResponseMultipleItemCallback( autofill_fill_response_item_h itemHandle, void *userData )
104 {
105   Dali::AutofillManager autofill = AutofillManager::Get();
106   Internal::Adaptor::AutofillManager& autofillImpl = Internal::Adaptor::GetImplementation( autofill );
107   Internal::Adaptor::AutofillManagerEcoreWl& autofillImplWl = static_cast<Internal::Adaptor::AutofillManagerEcoreWl&>( autofillImpl );
108   autofillImplWl.FillMultipleGroupItem( itemHandle, userData ); // Implementation here
109   return true;
110 }
111
112 // This callback is called according to the number of pairs to fill out.
113 static bool FillResponseGroupCallback( autofill_fill_response_group_h groupHandle, void *userData )
114 {
115   int* count = static_cast<int*>(userData);
116
117   // According to the number of group count, Retrieves all fill response items of each fill response group.
118   if( *count == 1 )
119   {
120     autofill_fill_response_group_foreach_item( groupHandle, FillResponseItemCallback, NULL );
121   }
122   else if( *count > 1 )
123   {
124     autofill_fill_response_group_foreach_item( groupHandle, FillResponseMultipleItemCallback, groupHandle );
125   }
126
127   return true;
128 }
129
130 // Callback to receive autofill fill response.
131 static void FillResponseCallback( autofill_h autofillHandle, autofill_fill_response_h fillResponseHandle, void *data )
132 {
133   if( !fillResponseHandle )
134   {
135     DALI_LOG_ERROR("Fill response handle is empty. \n");
136     return;
137   }
138
139   // Get fill response group count
140   int count = 0;
141   autofill_fill_response_get_group_count( fillResponseHandle, &count );
142   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::FillResponseCallback group count : %d \n", count );
143
144   // Retrieves all groups of each fill response.
145   autofill_fill_response_foreach_group( fillResponseHandle, FillResponseGroupCallback, &count );
146
147   if( count > 1 )
148   {
149     // Emits the signal to make a list of multiple data.
150     Dali::AutofillManager autofill = AutofillManager::Get();
151     autofill.ListEventSignal().Emit();
152   }
153 }
154 #endif // CAPI_AUTOFILL_SUPPORT
155
156 BaseHandle Create()
157 {
158   return Dali::AutofillManager::Get();
159 }
160
161 Dali::TypeRegistration typeRegistration( typeid(Dali::AutofillManager), typeid(Dali::BaseHandle), Create );
162
163 Dali::SignalConnectorType signalConnector1( typeRegistration, SIGNAL_AUTHENTICATION_RECEIVED, Dali::Internal::Adaptor::AutofillManagerEcoreWl::DoConnectSignal );
164 Dali::SignalConnectorType signalConnector2( typeRegistration, SIGNAL_FILL_RESPONSE_RECEIVED, Dali::Internal::Adaptor::AutofillManagerEcoreWl::DoConnectSignal );
165 Dali::SignalConnectorType signalConnector3( typeRegistration, SIGNAL_LIST_RECEIVED, Dali::Internal::Adaptor::AutofillManagerEcoreWl::DoConnectSignal );
166
167 } // unnamed namespace
168
169
170
171 Dali::AutofillManager AutofillManagerEcoreWl::Get()
172 {
173   Dali::AutofillManager autofill;
174   AutofillManagerEcoreWl *autofillPtr = NULL;
175
176   Dali::SingletonService service( SingletonService::Get() );
177   if( service )
178   {
179     // Check whether the singleton is already created
180     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AutofillManager ) );
181     if( handle )
182     {
183       // If so, downcast the handle
184       autofillPtr = dynamic_cast< AutofillManagerEcoreWl* >( handle.GetObjectPtr() );
185       autofill = Dali::AutofillManager( autofillPtr );
186     }
187     else if( Adaptor::IsAvailable() )
188     {
189       // Create instance and register singleton only if the adaptor is available
190       autofillPtr = new AutofillManagerEcoreWl();
191       autofill = Dali::AutofillManager( autofillPtr );
192       service.Register( typeid( autofill ), autofill );
193
194       // Connect Autofill daemon at the first time
195       autofillPtr->CreateContext();
196       autofillPtr->ConnectCallbacks();
197     }
198   }
199
200   return autofill;
201 }
202
203 AutofillManagerEcoreWl::AutofillManagerEcoreWl()
204 : mAutofillGroup(),
205   mAuthenticationServiceName(""),
206   mAuthenticationServiceMessage(""),
207   mAuthenticationServiceImagePath(""),
208   mFillItemId(""),
209   mFillItemPresentationText(""),
210   mFillItemValue(""),
211   mIsDataPresent( false ),
212   mIsAuthNeeded( false )
213 {
214 #ifdef CAPI_AUTOFILL_SUPPORT
215   mAutofillHandle =  NULL;
216 #endif // CAPI_AUTOFILL_SUPPORT
217 }
218
219 AutofillManagerEcoreWl::~AutofillManagerEcoreWl()
220 {
221   DeleteContext();
222 }
223
224 void AutofillManagerEcoreWl::CreateContext()
225 {
226   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::CreateContext\n" );
227
228 #ifdef CAPI_AUTOFILL_SUPPORT
229   int ret = autofill_create( &mAutofillHandle );
230   if( ret != AUTOFILL_ERROR_NONE )
231   {
232     DALI_LOG_ERROR( "Failed to create autofill handle : %d \n", ret );
233   }
234 #endif // CAPI_AUTOFILL_SUPPORT
235 }
236
237 void AutofillManagerEcoreWl::DeleteContext()
238 {
239   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::DeleteContext\n" );
240 #ifdef CAPI_AUTOFILL_SUPPORT
241   if( mAutofillHandle )
242   {
243     // Unsets the callback to receive the authentication information.
244     autofill_auth_info_unset_received_cb( mAutofillHandle );
245
246     autofill_destroy( mAutofillHandle );
247     mAutofillHandle = NULL;
248   }
249 #endif // CAPI_AUTOFILL_SUPPORT
250 }
251
252 // Callbacks for connecting to autofill daemon.
253 void AutofillManagerEcoreWl::ConnectCallbacks()
254 {
255 #ifdef CAPI_AUTOFILL_SUPPORT
256   if( mAutofillHandle )
257   {
258     DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::ConnectCallbacks\n" );
259
260     int ret = autofill_connect( mAutofillHandle, ConnectionStatusChangedCallback, NULL );
261     if( ret != AUTOFILL_ERROR_NONE )
262     {
263       DALI_LOG_ERROR( "Failed to connect : %d \n", ret );
264     }
265
266     // Sets the callback to receive the authentication information.
267     autofill_auth_info_set_received_cb( mAutofillHandle, AuthInfoCallback, NULL );
268
269     // Sets the callback to receive autofill fill response.
270     autofill_fill_response_set_received_cb( mAutofillHandle, FillResponseCallback, NULL );
271   }
272 #endif // CAPI_AUTOFILL_SUPPORT
273 }
274
275
276 /////////////////////////////////////////////// Autofill Callback implementation ///////////////////////////////////////////////
277
278 #ifdef CAPI_AUTOFILL_SUPPORT
279
280 autofill_h AutofillManagerEcoreWl::GetAutofillHandle()
281 {
282   return mAutofillHandle;
283 }
284
285 // Implementation to receive the authentication information.
286 void AutofillManagerEcoreWl::ReceiveAuthInfo( autofill_auth_info_h authInfoHandle, void *data )
287 {
288   bool autofillDataPresent = false;
289   bool authenticationNeeded = false;
290   char* serviceName = NULL;
291   char* serviceMessage = NULL;
292   char* serviceLogoImagePath = NULL;
293   char* groupId = NULL;
294
295   // Gets the authentication information which is set by Autofill Service framework.
296   autofill_auth_info_get_view_id( authInfoHandle, &groupId );
297   autofill_auth_info_get_autofill_data_present( authInfoHandle, &autofillDataPresent );
298   autofill_auth_info_get_authentication_needed( authInfoHandle, &authenticationNeeded );
299
300   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::ReceiveAuthInfo group id : %s, Is autofill data present ? : %s, Is authentication needed ? : %s \n",
301                                               groupId, autofillDataPresent ? "true" : "false", authenticationNeeded ? "true" : "false" );
302
303   for( std::vector<Dali::AutofillGroup>::iterator iter = mAutofillGroupList.begin(), endIter = mAutofillGroupList.end(); iter != endIter; ++iter )
304   {
305     const std::string id = ( *iter ).GetId();
306     if( id.compare( groupId ) == 0 )
307     {
308       mAutofillGroup = ( *iter );
309       break;
310     }
311   }
312   // Sets the 'autofill data present' and 'authentication needed' attributes in autofill authentication information.
313   mIsDataPresent = autofillDataPresent;
314   mIsAuthNeeded = authenticationNeeded;
315
316   if( groupId )
317   {
318     free( groupId );
319   }
320
321   if( !autofillDataPresent )
322   {
323     DALI_LOG_ERROR( " -> The autofill data is not present now. \n" );
324     return;
325   }
326
327   // If autofill authentication is needed, get authentication service information and set to DALi member variables.
328   if( authenticationNeeded )
329   {
330     // Gets the authentication service information which is set by Autofill Service framework.
331     autofill_auth_info_get_service_name( authInfoHandle, &serviceName );
332     autofill_auth_info_get_service_message( authInfoHandle, &serviceMessage );
333     autofill_auth_info_get_service_logo_image_path( authInfoHandle, &serviceLogoImagePath );
334
335     DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::ReceiveAuthInfo service name : %s, logo path : %s, message : '%s' \n",
336                                                 serviceName, serviceLogoImagePath, serviceMessage );
337
338     // Sets the authentication service information in order to use in other components.
339     if( serviceName )
340     {
341       mAuthenticationServiceName = serviceName;
342       free( serviceName );
343     }
344
345     if( serviceMessage )
346     {
347       mAuthenticationServiceMessage = serviceMessage;
348       free( serviceMessage );
349     }
350
351     if( serviceLogoImagePath )
352     {
353       mAuthenticationServiceImagePath = serviceLogoImagePath;
354       free( serviceLogoImagePath );
355     }
356
357     // Emits the signal to receive the authentication information.
358     mAuthReceivedSignal.Emit();
359   }
360   else
361   {
362     // If Authentication is not needed, sends fill request directly to fill the data.
363     mAutofillGroup.SendFillRequest();
364   }
365 }
366
367 // Implementation to fill out the data
368 void AutofillManagerEcoreWl::FillGroupItem( autofill_fill_response_item_h itemHandle, void *userData )
369 {
370   char* id = NULL;
371   char* value = NULL;
372   char* presentationText = NULL;
373
374   // Gets the fill response information which is set by Autofill Service framework.
375   autofill_fill_response_item_get_id( itemHandle, &id );
376   autofill_fill_response_item_get_presentation_text( itemHandle, &presentationText );
377   autofill_fill_response_item_get_value( itemHandle, &value );
378
379   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::FillResponseItemCallback item id : %s, value : %s, presentation text : %s\n",
380                                               id, value, presentationText );
381
382   // Sets the fill response information in order to use in other components.
383   if( id )
384   {
385     mFillItemId = id;
386     free( id );
387   }
388
389   if( presentationText )
390   {
391     mFillItemPresentationText = presentationText;
392     free( presentationText );
393   }
394
395   if( value )
396   {
397     mFillItemValue = value;
398     free( value );
399   }
400
401   Dali::AutofillItem item = mAutofillGroup.GetAutofillItem( mFillItemId );
402   Internal::Adaptor::AutofillItem& itemImpl = Internal::Adaptor::GetImplementation( item );
403   itemImpl.AddPresentationList( mFillItemPresentationText );
404   itemImpl.AddFillValueList( mFillItemValue );
405
406   // Emits the signal to fill the data in text input field.
407   mFillReceivedSignal.Emit( item );
408
409 }
410
411 // Implementation to fill out the data when the group count is more than one.
412 void AutofillManagerEcoreWl::FillMultipleGroupItem( autofill_fill_response_item_h itemHandle, void *userData )
413 {
414   char* id = NULL;
415   char* value = NULL;
416   char* presentationText = NULL;
417
418   // Gets the fill response information which is set by Autofill Service framework.
419   autofill_fill_response_item_get_id( itemHandle, &id );
420   autofill_fill_response_item_get_presentation_text( itemHandle, &presentationText );
421   autofill_fill_response_item_get_value( itemHandle, &value );
422
423   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::FillResponseMultipleItemCallback item id : %s, value : %s, presentation text : %s\n",
424                                               id, value, presentationText );
425
426   // Sets the fill response information in order to use in other components.
427   if( id )
428   {
429     mFillItemId = id;
430     free( id );
431   }
432
433   if( presentationText )
434   {
435     mFillItemPresentationText = presentationText;
436     free( presentationText );
437   }
438
439   if( value )
440   {
441     mFillItemValue = value;
442     free( value );
443   }
444
445   Dali::AutofillItem item = mAutofillGroup.GetAutofillItem( mFillItemId );
446   Internal::Adaptor::AutofillItem& itemImpl = Internal::Adaptor::GetImplementation( item );
447   itemImpl.AddPresentationList( mFillItemPresentationText );
448   itemImpl.AddFillValueList( mFillItemValue );
449
450 }
451 #endif // CAPI_AUTOFILL_SUPPORT
452
453
454 /////////////////////////////////////////////// Autofill Item and Group ///////////////////////////////////////////////
455
456 Dali::AutofillItem AutofillManagerEcoreWl::CreateAutofillItem( const std::string& id, const std::string& label, Dali::AutofillItem::Hint hint, bool isSensitive )
457 {
458   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::CreateAutofillItem \n" );
459
460   Dali::AutofillItem item = AutofillItem::New( id, label, hint, isSensitive );
461   mAutofillItemList.push_back( item );
462
463   return mAutofillItemList.back();
464 }
465
466 Dali::AutofillGroup AutofillManagerEcoreWl::CreateAutofillGroup( const std::string& groupId )
467 {
468   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::CreateAutofillGroup \n" );
469
470   Dali::AutofillGroup group = AutofillGroup::New( groupId );
471   mAutofillGroupList.push_back( group );
472
473   return mAutofillGroupList.back();
474 }
475
476
477 /////////////////////////////////////////////// Autofill Authentication Information ///////////////////////////////////////////////
478
479 bool AutofillManagerEcoreWl::IsAutofillDataPresent() const
480 {
481   return mIsDataPresent;
482 }
483
484 bool AutofillManagerEcoreWl::IsAuthenticationNeeded() const
485 {
486   return mIsAuthNeeded;
487 }
488
489 const std::string& AutofillManagerEcoreWl::GetAuthenticationServiceName() const
490 {
491   return mAuthenticationServiceName;
492 }
493
494 const std::string& AutofillManagerEcoreWl::GetAuthenticationServiceMessage() const
495 {
496   return mAuthenticationServiceMessage;
497 }
498
499 const std::string& AutofillManagerEcoreWl::GetAuthenticationServiceImagePath() const
500 {
501   return mAuthenticationServiceImagePath;
502 }
503
504
505 /////////////////////////////////////////////// Autofill Fill Response ///////////////////////////////////////////////
506
507 const std::string& AutofillManagerEcoreWl::GetFillItemId() const
508 {
509   return mFillItemId;
510 }
511
512 const std::string& AutofillManagerEcoreWl::GetFillItemPresentationText() const
513 {
514   return mFillItemPresentationText;
515 }
516
517 const std::string& AutofillManagerEcoreWl::GetFillItemValue() const
518 {
519   return mFillItemValue;
520 }
521
522 void AutofillManagerEcoreWl::SaveAutofillData( Dali::AutofillGroup group )
523 {
524   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::SaveAutofillData -> Sends request to store data. \n" );
525
526 #ifdef CAPI_AUTOFILL_SUPPORT
527   Internal::Adaptor::AutofillGroup& groupImpl = Internal::Adaptor::GetImplementation( group );
528   Internal::Adaptor::AutofillGroupEcoreWl& groupImplWl = static_cast<Internal::Adaptor::AutofillGroupEcoreWl&>( groupImpl );
529
530   // Sends request to save autofill data.
531   int ret = autofill_commit( mAutofillHandle, groupImplWl.GetAutofillSaveGroupHandle() );
532   if( ret != AUTOFILL_ERROR_NONE )
533   {
534     DALI_LOG_ERROR( "Failed to request auth info. error : %d \n", ret );
535   }
536 #endif // CAPI_AUTOFILL_SUPPORT
537 }
538
539 // Signals
540 AutofillManagerEcoreWl::AuthSignalType& AutofillManagerEcoreWl::AuthenticationReceivedSignal()
541 {
542   return mAuthReceivedSignal;
543 }
544
545 AutofillManagerEcoreWl::FillSignalType& AutofillManagerEcoreWl::FillResponseReceivedSignal()
546 {
547   return mFillReceivedSignal;
548 }
549
550 AutofillManagerEcoreWl::ListSignalType& AutofillManagerEcoreWl::ListEventSignal()
551 {
552   return mListReceivedSignal;
553 }
554
555 bool AutofillManagerEcoreWl::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
556 {
557   Dali::BaseHandle handle( object );
558
559   bool connected( true );
560   AutofillManagerEcoreWl* manager = dynamic_cast< AutofillManagerEcoreWl* >( object );
561
562   if( manager )
563   {
564     if( 0 == signalName.compare( SIGNAL_AUTHENTICATION_RECEIVED ) )
565     {
566       manager->AuthenticationReceivedSignal().Connect( tracker, functor );
567     }
568     else if( 0 == signalName.compare( SIGNAL_FILL_RESPONSE_RECEIVED ) )
569     {
570       manager->FillResponseReceivedSignal().Connect( tracker, functor );
571     }
572     else if( 0 == signalName.compare( SIGNAL_LIST_RECEIVED ) )
573     {
574       manager->ListEventSignal().Connect( tracker, functor );
575     }
576     else
577     {
578       // signalName does not match any signal
579       connected = false;
580     }
581   }
582
583   return connected;
584 }
585
586 } // Adaptor
587
588 } // Internal
589
590 } // Dali