[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/devel-api/common/singleton-service.h>
24 #include <dali/integration-api/debug.h>
25
26 // INTERNAL INCLUDES
27 #include <dali/internal/adaptor/common/adaptor-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     mAuthenticationServiceName = serviceName;
340     mAuthenticationServiceMessage = serviceMessage;
341     mAuthenticationServiceImagePath = serviceLogoImagePath;
342
343     // Emits the signal to receive the authentication information.
344     mAuthReceivedSignal.Emit();
345
346     if( serviceMessage )
347     {
348       free( serviceMessage );
349     }
350
351     if( serviceName )
352     {
353       free( serviceName );
354     }
355
356     if( serviceLogoImagePath )
357     {
358       free( serviceLogoImagePath );
359     }
360   }
361   else
362   {
363     // If Authentication is not needed, sends fill request directly to fill the data.
364     mAutofillGroup.SendFillRequest();
365   }
366 }
367
368 // Implementation to fill out the data
369 void AutofillManagerEcoreWl::FillGroupItem( autofill_fill_response_item_h itemHandle, void *userData )
370 {
371   char* id = NULL;
372   char* value = NULL;
373   char* presentationText = NULL;
374
375   // Gets the fill response information which is set by Autofill Service framework.
376   autofill_fill_response_item_get_id( itemHandle, &id );
377   autofill_fill_response_item_get_presentation_text( itemHandle, &presentationText );
378   autofill_fill_response_item_get_value( itemHandle, &value );
379
380   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::FillResponseItemCallback item id : %s, value : %s, presentation text : %s\n",
381                                               id, value, presentationText );
382
383   // Sets the fill response information in order to use in other components.
384   mFillItemId = id;
385   mFillItemPresentationText = presentationText;
386   mFillItemValue = value;
387
388   Dali::AutofillItem item = mAutofillGroup.GetAutofillItem( id );
389   Internal::Adaptor::AutofillItem& itemImpl = Internal::Adaptor::GetImplementation( item );
390   itemImpl.AddPresentationList( presentationText );
391   itemImpl.AddFillValueList( value );
392
393   // Emits the signal to fill the data in text input field.
394   mFillReceivedSignal.Emit( item );
395
396   if( id )
397   {
398     free( id );
399   }
400
401   if( value )
402   {
403     free( value );
404   }
405
406   if( presentationText )
407   {
408     free( presentationText );
409   }
410
411 }
412
413 // Implementation to fill out the data when the group count is more than one.
414 void AutofillManagerEcoreWl::FillMultipleGroupItem( autofill_fill_response_item_h itemHandle, void *userData )
415 {
416   char* id = NULL;
417   char* value = NULL;
418   char* presentationText = NULL;
419
420   // Gets the fill response information which is set by Autofill Service framework.
421   autofill_fill_response_item_get_id( itemHandle, &id );
422   autofill_fill_response_item_get_presentation_text( itemHandle, &presentationText );
423   autofill_fill_response_item_get_value( itemHandle, &value );
424
425   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::FillResponseMultipleItemCallback item id : %s, value : %s, presentation text : %s\n",
426                                               id, value, presentationText );
427
428   // Sets the fill response information in order to use in other components.
429   mFillItemId = id;
430   mFillItemPresentationText = presentationText;
431   mFillItemValue = value;
432
433   Dali::AutofillItem item = mAutofillGroup.GetAutofillItem( id );
434   Internal::Adaptor::AutofillItem& itemImpl = Internal::Adaptor::GetImplementation( item );
435   itemImpl.AddPresentationList( presentationText );
436   itemImpl.AddFillValueList( value );
437
438   if( id )
439   {
440     free( id );
441   }
442
443   if( value )
444   {
445     free( value );
446   }
447
448   if( presentationText )
449   {
450     free( presentationText );
451   }
452 }
453 #endif // CAPI_AUTOFILL_SUPPORT
454
455
456 /////////////////////////////////////////////// Autofill Item and Group ///////////////////////////////////////////////
457
458 Dali::AutofillItem AutofillManagerEcoreWl::CreateAutofillItem( const std::string& id, const std::string& label, Dali::AutofillItem::Hint hint, bool isSensitive )
459 {
460   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::CreateAutofillItem \n" );
461
462   Dali::AutofillItem item = AutofillItem::New( id, label, hint, isSensitive );
463   mAutofillItemList.push_back( item );
464
465   return mAutofillItemList.back();
466 }
467
468 Dali::AutofillGroup AutofillManagerEcoreWl::CreateAutofillGroup( const std::string& groupId )
469 {
470   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::CreateAutofillGroup \n" );
471
472   Dali::AutofillGroup group = AutofillGroup::New( groupId );
473   mAutofillGroupList.push_back( group );
474
475   return mAutofillGroupList.back();
476 }
477
478
479 /////////////////////////////////////////////// Autofill Authentication Information ///////////////////////////////////////////////
480
481 bool AutofillManagerEcoreWl::IsAutofillDataPresent() const
482 {
483   return mIsDataPresent;
484 }
485
486 bool AutofillManagerEcoreWl::IsAuthenticationNeeded() const
487 {
488   return mIsAuthNeeded;
489 }
490
491 const std::string& AutofillManagerEcoreWl::GetAuthenticationServiceName() const
492 {
493   return mAuthenticationServiceName;
494 }
495
496 const std::string& AutofillManagerEcoreWl::GetAuthenticationServiceMessage() const
497 {
498   return mAuthenticationServiceMessage;
499 }
500
501 const std::string& AutofillManagerEcoreWl::GetAuthenticationServiceImagePath() const
502 {
503   return mAuthenticationServiceImagePath;
504 }
505
506
507 /////////////////////////////////////////////// Autofill Fill Response ///////////////////////////////////////////////
508
509 const std::string& AutofillManagerEcoreWl::GetFillItemId() const
510 {
511   return mFillItemId;
512 }
513
514 const std::string& AutofillManagerEcoreWl::GetFillItemPresentationText() const
515 {
516   return mFillItemPresentationText;
517 }
518
519 const std::string& AutofillManagerEcoreWl::GetFillItemValue() const
520 {
521   return mFillItemValue;
522 }
523
524 void AutofillManagerEcoreWl::SaveAutofillData( Dali::AutofillGroup group )
525 {
526   DALI_LOG_INFO( gLogFilter, Debug::General, "AutofillManagerEcoreWl::SaveAutofillData -> Sends request to store data. \n" );
527
528 #ifdef CAPI_AUTOFILL_SUPPORT
529   Internal::Adaptor::AutofillGroup& groupImpl = Internal::Adaptor::GetImplementation( group );
530   Internal::Adaptor::AutofillGroupEcoreWl& groupImplWl = static_cast<Internal::Adaptor::AutofillGroupEcoreWl&>( groupImpl );
531
532   // Sends request to save autofill data.
533   int ret = autofill_commit( mAutofillHandle, groupImplWl.GetAutofillSaveGroupHandle() );
534   if( ret != AUTOFILL_ERROR_NONE )
535   {
536     DALI_LOG_ERROR( "Failed to request auth info. error : %d \n", ret );
537   }
538 #endif // CAPI_AUTOFILL_SUPPORT
539 }
540
541 // Signals
542 AutofillManagerEcoreWl::AuthSignalType& AutofillManagerEcoreWl::AuthenticationReceivedSignal()
543 {
544   return mAuthReceivedSignal;
545 }
546
547 AutofillManagerEcoreWl::FillSignalType& AutofillManagerEcoreWl::FillResponseReceivedSignal()
548 {
549   return mFillReceivedSignal;
550 }
551
552 AutofillManagerEcoreWl::ListSignalType& AutofillManagerEcoreWl::ListEventSignal()
553 {
554   return mListReceivedSignal;
555 }
556
557 bool AutofillManagerEcoreWl::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
558 {
559   Dali::BaseHandle handle( object );
560
561   bool connected( true );
562   AutofillManagerEcoreWl* manager = dynamic_cast< AutofillManagerEcoreWl* >( object );
563
564   if( manager )
565   {
566     if( 0 == signalName.compare( SIGNAL_AUTHENTICATION_RECEIVED ) )
567     {
568       manager->AuthenticationReceivedSignal().Connect( tracker, functor );
569     }
570     else if( 0 == signalName.compare( SIGNAL_FILL_RESPONSE_RECEIVED ) )
571     {
572       manager->FillResponseReceivedSignal().Connect( tracker, functor );
573     }
574     else if( 0 == signalName.compare( SIGNAL_LIST_RECEIVED ) )
575     {
576       manager->ListEventSignal().Connect( tracker, functor );
577     }
578     else
579     {
580       // signalName does not match any signal
581       connected = false;
582     }
583   }
584
585   return connected;
586 }
587
588 } // Adaptor
589
590 } // Internal
591
592 } // Dali