diff --git a/flutter/shell/platform/tizen/channels/text_input_channel.cc b/flutter/shell/platform/tizen/channels/text_input_channel.cc index 92a65d7..1b56107 100644 --- a/flutter/shell/platform/tizen/channels/text_input_channel.cc +++ b/flutter/shell/platform/tizen/channels/text_input_channel.cc @@ -323,7 +323,7 @@ void TextInputChannel::HandleMethodCall( SendStateUpdate(); #ifndef WEARABLE_PROFILE } else if (method.compare(kRequestAutofillMethod) == 0) { - TizenAutofill::GetInstance().RequestAutofill(autofill_hints_, autofill_id_); + TizenAutofill::GetInstance().RequestAutofill(autofill_id_, autofill_hints_); #endif } else { result->NotImplemented(); diff --git a/flutter/shell/platform/tizen/nui_autofill_popup.cc b/flutter/shell/platform/tizen/nui_autofill_popup.cc index 708ef00..d723900 100644 --- a/flutter/shell/platform/tizen/nui_autofill_popup.cc +++ b/flutter/shell/platform/tizen/nui_autofill_popup.cc @@ -54,33 +54,35 @@ void NuiAutofillPopup::Prepare() { void NuiAutofillPopup::Show(Dali::Actor* actor) { const std::vector>& items = TizenAutofill::GetInstance().GetResponseItems(); - if (!items.empty()) { - Prepare(); - Dali::Toolkit::TableView content = - Dali::Toolkit::TableView::New(items.size(), 1); - content.SetResizePolicy(Dali::ResizePolicy::FILL_TO_PARENT, - Dali::Dimension::ALL_DIMENSIONS); - content.SetProperty(Dali::Actor::Property::PADDING, - Dali::Vector4(10, 10, 0, 0)); - for (uint32_t i = 0; i < items.size(); ++i) { - Dali::Toolkit::TextLabel label = - Dali::Toolkit::TextLabel::New(items[i]->label_); - label.SetProperty(Dali::Actor::Property::NAME, items[i]->value_); - label.SetResizePolicy(Dali::ResizePolicy::DIMENSION_DEPENDENCY, - Dali::Dimension::HEIGHT); - label.SetProperty(Dali::Toolkit::TextLabel::Property::TEXT_COLOR, - Dali::Color::WHITE_SMOKE); - label.SetProperty(Dali::Toolkit::TextLabel::Property::POINT_SIZE, 7.0f); - label.TouchedSignal().Connect(this, &NuiAutofillPopup::Touched); - content.AddChild(label, Dali::Toolkit::TableView::CellPosition(i, 0)); - content.SetFitHeight(i); - } - popup_.SetProperty(Dali::Actor::Property::SIZE, - Dali::Vector2(140.0f, 35.0f * items.size())); - popup_.SetContent(content); - popup_.SetDisplayState(Dali::Toolkit::Popup::SHOWN); - actor->Add(popup_); + if (items.empty()) { + return; } + + Prepare(); + Dali::Toolkit::TableView content = + Dali::Toolkit::TableView::New(items.size(), 1); + content.SetResizePolicy(Dali::ResizePolicy::FILL_TO_PARENT, + Dali::Dimension::ALL_DIMENSIONS); + content.SetProperty(Dali::Actor::Property::PADDING, + Dali::Vector4(10, 10, 0, 0)); + for (uint32_t i = 0; i < items.size(); ++i) { + Dali::Toolkit::TextLabel label = + Dali::Toolkit::TextLabel::New(items[i]->label_); + label.SetProperty(Dali::Actor::Property::NAME, items[i]->value_); + label.SetResizePolicy(Dali::ResizePolicy::DIMENSION_DEPENDENCY, + Dali::Dimension::HEIGHT); + label.SetProperty(Dali::Toolkit::TextLabel::Property::TEXT_COLOR, + Dali::Color::WHITE_SMOKE); + label.SetProperty(Dali::Toolkit::TextLabel::Property::POINT_SIZE, 7.0f); + label.TouchedSignal().Connect(this, &NuiAutofillPopup::Touched); + content.AddChild(label, Dali::Toolkit::TableView::CellPosition(i, 0)); + content.SetFitHeight(i); + } + popup_.SetProperty(Dali::Actor::Property::SIZE, + Dali::Vector2(140.0f, 35.0f * items.size())); + popup_.SetContent(content); + popup_.SetDisplayState(Dali::Toolkit::Popup::SHOWN); + actor->Add(popup_); } } // namespace flutter diff --git a/flutter/shell/platform/tizen/nui_autofill_popup.h b/flutter/shell/platform/tizen/nui_autofill_popup.h index 8df10ce..1295d42 100644 --- a/flutter/shell/platform/tizen/nui_autofill_popup.h +++ b/flutter/shell/platform/tizen/nui_autofill_popup.h @@ -13,8 +13,6 @@ namespace flutter { class NuiAutofillPopup : public Dali::ConnectionTracker { public: - void Prepare(); - void Show(Dali::Actor* actor); void SetOnCommit(std::function callback) { @@ -22,6 +20,8 @@ class NuiAutofillPopup : public Dali::ConnectionTracker { } private: + void Prepare(); + void Hidden(); void OutsideTouched(); diff --git a/flutter/shell/platform/tizen/tizen_autofill.cc b/flutter/shell/platform/tizen/tizen_autofill.cc index 484decf..b3e27dd 100644 --- a/flutter/shell/platform/tizen/tizen_autofill.cc +++ b/flutter/shell/platform/tizen/tizen_autofill.cc @@ -11,123 +11,139 @@ #include "flutter/shell/platform/tizen/logger.h" -TizenAutofill::TizenAutofill() { - Initailize(); -} +namespace flutter { -TizenAutofill::~TizenAutofill() { - autofill_fill_response_unset_received_cb(autofill_); - autofill_destroy(autofill_); -} +namespace { -void TizenAutofill::Initailize() { - int ret = AUTOFILL_ERROR_NONE; - if (!autofill_) { - ret = autofill_create(&autofill_); - if (ret != AUTOFILL_ERROR_NONE) { - FT_LOG(Error) << "Fail to create autofill handle."; - return; - } +std::optional ConvertAutofillHint(std::string hint) { + if (hint == "creditCardExpirationDate") { + return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE; + } else if (hint == "creditCardExpirationDay") { + return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY; + } else if (hint == "creditCardExpirationMonth") { + return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH; + } else if (hint == "creditCardExpirationYear") { + return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR; + } else if (hint == "email") { + return AUTOFILL_HINT_EMAIL_ADDRESS; + } else if (hint == "name") { + return AUTOFILL_HINT_NAME; + } else if (hint == "telephoneNumber") { + return AUTOFILL_HINT_PHONE; + } else if (hint == "postalAddress") { + return AUTOFILL_HINT_POSTAL_ADDRESS; + } else if (hint == "postalCode") { + return AUTOFILL_HINT_POSTAL_CODE; + } else if (hint == "username") { + return AUTOFILL_HINT_ID; + } else if (hint == "password") { + return AUTOFILL_HINT_PASSWORD; + } else if (hint == "creditCardSecurityCode") { + return AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE; } + FT_LOG(Error) << "Not supported autofill hint : " << hint; + return std::nullopt; +} - ret = autofill_connect( - autofill_, - [](autofill_h autofill, autofill_connection_status_e status, - void* user_data) { TizenAutofill::GetInstance().SetConnected(true); }, - nullptr); - if (ret != AUTOFILL_ERROR_NONE) { - FT_LOG(Error) << "Fail to connect to the autofill daemon."; - return; +bool StoreFillResponseItem(autofill_fill_response_item_h item, void* data) { + char* id = nullptr; + char* value = nullptr; + char* label = nullptr; + + autofill_fill_response_item_get_id(item, &id); + autofill_fill_response_item_get_presentation_text(item, &label); + autofill_fill_response_item_get_value(item, &value); + std::unique_ptr response_item = + std::make_unique(); + response_item->id_ = std::string(id); + response_item->value_ = std::string(value); + response_item->label_ = std::string(label); + + TizenAutofill* tizen_autofill = static_cast(data); + tizen_autofill->StoreResponseItem(move(response_item)); + if (id) { + free(id); } - ret = autofill_fill_response_set_received_cb( - autofill_, - [](autofill_h autofill, autofill_fill_response_h fill_response, - void* data) { - int count = 0; - autofill_fill_response_get_group_count(fill_response, &count); - autofill_fill_response_foreach_group( - fill_response, - [](autofill_fill_response_group_h group, void* user_data) { - autofill_fill_response_group_foreach_item( - group, - [](autofill_fill_response_item_h item, void* user_data) { - char* id = nullptr; - char* value = nullptr; - char* label = nullptr; - - autofill_fill_response_item_get_id(item, &id); - autofill_fill_response_item_get_presentation_text(item, - &label); - autofill_fill_response_item_get_value(item, &value); - - std::unique_ptr response_item = - std::make_unique(); - response_item->id_ = std::string(id); - response_item->value_ = std::string(value); - response_item->label_ = std::string(label); - - TizenAutofill::GetInstance().StoreResponseItem( - move(response_item)); - - if (id) { - free(id); - } - - if (value) { - free(value); - } - - if (label) { - free(label); - } - - return true; - }, - group); - return true; - }, - &count); - TizenAutofill::GetInstance().OnPopup(); - }, - nullptr); - if (ret != AUTOFILL_ERROR_NONE) { - FT_LOG(Error) << "Fail to set fill response received callback."; - return; + if (value) { + free(value); } - response_items_.clear(); - initailzed_ = true; + if (label) { + free(label); + } + return true; } -void TizenAutofill::RequestAutofill(std::vector hints, - std::string id) { - if (!initailzed_) { - Initailize(); - return; +bool StoreForeachItem(autofill_fill_response_group_h group, void* data) { + autofill_fill_response_group_foreach_item(group, StoreFillResponseItem, data); + return true; +}; + +void ResponseReceived(autofill_h autofill, + autofill_fill_response_h fill_response, + void* data) { + autofill_fill_response_foreach_group(fill_response, StoreForeachItem, data); + TizenAutofill* tizen_autofill = static_cast(data); + tizen_autofill->OnPopup(); +}; + +autofill_save_item_h CreateSaveItem(const AutofillItem& item) { + autofill_save_item_h save_item = nullptr; + int ret = autofill_save_item_create(&save_item); + if (ret != AUTOFILL_ERROR_NONE) { + FT_LOG(Error) << "Failed to create autofill save item."; + return nullptr; } - if (!connected_) { - return; + autofill_save_item_set_autofill_hint(save_item, item.hint_); + autofill_save_item_set_id(save_item, item.id_.c_str()); + autofill_save_item_set_label(save_item, item.label_.c_str()); + autofill_save_item_set_sensitive_data(save_item, item.sensitive_data_); + autofill_save_item_set_value(save_item, item.value_.c_str()); + + return save_item; +} + +autofill_save_view_info_h CreateSaveViewInfo(const std::string& view_id, + const AutofillItem& item) { + autofill_save_item_h save_item = CreateSaveItem(item); + if (save_item == nullptr) { + return nullptr; } char* app_id = nullptr; app_get_id(&app_id); - autofill_view_info_h view_info = nullptr; - autofill_view_info_create(&view_info); - autofill_view_info_set_app_id(view_info, app_id); - autofill_view_info_set_view_id(view_info, id.c_str()); + autofill_save_view_info_h save_view_info = nullptr; + int ret = autofill_save_view_info_create(&save_view_info); + if (ret != AUTOFILL_ERROR_NONE) { + FT_LOG(Error) << "Failed to create autofill save view info."; + return nullptr; + } + autofill_save_view_info_set_app_id(save_view_info, app_id); + autofill_save_view_info_set_view_id(save_view_info, view_id.c_str()); + autofill_save_view_info_add_item(save_view_info, save_item); if (app_id) { free(app_id); } + return save_view_info; +} + +void AddItemsToViewInfo(const autofill_view_info_h& view_info, + const std::string id, + const std::vector& hints) { for (auto hint : hints) { std::optional autofill_hint = ConvertAutofillHint(hint); if (autofill_hint.has_value()) { autofill_item_h item = nullptr; - autofill_item_create(&item); + int ret = autofill_item_create(&item); + if (ret != AUTOFILL_ERROR_NONE) { + FT_LOG(Error) << "Failed to create autofill item."; + continue; + } autofill_item_set_autofill_hint(item, autofill_hint.value()); autofill_item_set_id(item, id.c_str()); autofill_item_set_sensitive_data(item, false); @@ -135,82 +151,121 @@ void TizenAutofill::RequestAutofill(std::vector hints, autofill_item_destroy(item); } } +} - int ret = autofill_fill_request(autofill_, view_info); +autofill_view_info_h CreateViewInfo(const std::string& id, + const std::vector& hints) { + char* app_id = nullptr; + app_get_id(&app_id); + + autofill_view_info_h view_info = nullptr; + int ret = autofill_view_info_create(&view_info); if (ret != AUTOFILL_ERROR_NONE) { - FT_LOG(Error) << "Fail to request autofill"; + FT_LOG(Error) << "Failed to create autofill view info."; + return nullptr; } - autofill_view_info_destroy(view_info); + autofill_view_info_set_app_id(view_info, app_id); + autofill_view_info_set_view_id(view_info, id.c_str()); + + if (app_id) { + free(app_id); + } + + AddItemsToViewInfo(view_info, id, hints); + + return view_info; +} + +} // namespace + +TizenAutofill::TizenAutofill() { + Initialize(); +} + +TizenAutofill::~TizenAutofill() { + autofill_fill_response_unset_received_cb(autofill_); + autofill_destroy(autofill_); +} + +void TizenAutofill::Initialize() { + int ret = AUTOFILL_ERROR_NONE; + if (!autofill_) { + ret = autofill_create(&autofill_); + if (ret != AUTOFILL_ERROR_NONE) { + FT_LOG(Error) << "Failed to create autofill handle."; + return; + } + } + + ret = autofill_connect( + autofill_, + [](autofill_h autofill, autofill_connection_status_e status, void* data) { + TizenAutofill* tizen_autofill = static_cast(data); + if (status == AUTOFILL_CONNECTION_STATUS_CONNECTED) { + tizen_autofill->SetConnected(true); + } else { + tizen_autofill->SetConnected(false); + } + }, + this); + if (ret != AUTOFILL_ERROR_NONE) { + FT_LOG(Error) << "Failed to connect to the autofill daemon."; + return; + } + + autofill_fill_response_set_received_cb(autofill_, ResponseReceived, this); response_items_.clear(); + is_initialized_ = true; } -void TizenAutofill::RegisterItem(std::string view_id, AutofillItem item) { - if (!initailzed_) { - Initailize(); +void TizenAutofill::RequestAutofill(const std::string& id, + const std::vector& hints) { + if (!is_initialized_) { + Initialize(); return; } - if (!connected_) { + if (!is_connected_) { return; } - autofill_save_item_h save_item = nullptr; - autofill_save_item_create(&save_item); - autofill_save_item_set_autofill_hint(save_item, item.hint_); - autofill_save_item_set_id(save_item, item.id_.c_str()); - autofill_save_item_set_label(save_item, item.label_.c_str()); - autofill_save_item_set_sensitive_data(save_item, item.sensitive_data_); - autofill_save_item_set_value(save_item, item.value_.c_str()); + autofill_view_info_h view_info = CreateViewInfo(id, hints); + if (view_info == nullptr) { + return; + } - char* app_id = nullptr; - app_get_id(&app_id); + int ret = autofill_fill_request(autofill_, view_info); + if (ret != AUTOFILL_ERROR_NONE) { + FT_LOG(Error) << "Failed to request autofill."; + } + autofill_view_info_destroy(view_info); - autofill_save_view_info_h save_view_info = nullptr; - autofill_save_view_info_create(&save_view_info); - autofill_save_view_info_set_app_id(save_view_info, app_id); - autofill_save_view_info_set_view_id(save_view_info, view_id.c_str()); - autofill_save_view_info_add_item(save_view_info, save_item); + response_items_.clear(); +} - if (app_id) { - free(app_id); +void TizenAutofill::RegisterItem(const std::string& view_id, + const AutofillItem& item) { + if (!is_initialized_) { + Initialize(); + return; + } + + if (!is_connected_) { + return; + } + + autofill_save_view_info_h save_view_info = CreateSaveViewInfo(view_id, item); + if (save_view_info == nullptr) { + return; } int ret = autofill_commit(autofill_, save_view_info); if (ret != AUTOFILL_ERROR_NONE) { - FT_LOG(Error) << "Fail to register autofill item."; + FT_LOG(Error) << "Failed to register autofill item."; } autofill_save_view_info_destroy(save_view_info); } -std::optional TizenAutofill::ConvertAutofillHint( - std::string hint) { - if (hint == "creditCardExpirationDate") { - return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE; - } else if (hint == "creditCardExpirationDay") { - return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY; - } else if (hint == "creditCardExpirationMonth") { - return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH; - } else if (hint == "creditCardExpirationYear") { - return AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR; - } else if (hint == "email") { - return AUTOFILL_HINT_EMAIL_ADDRESS; - } else if (hint == "name") { - return AUTOFILL_HINT_NAME; - } else if (hint == "telephoneNumber") { - return AUTOFILL_HINT_PHONE; - } else if (hint == "postalAddress") { - return AUTOFILL_HINT_POSTAL_ADDRESS; - } else if (hint == "postalCode") { - return AUTOFILL_HINT_POSTAL_CODE; - } else if (hint == "username") { - return AUTOFILL_HINT_ID; - } else if (hint == "password") { - return AUTOFILL_HINT_PASSWORD; - } else if (hint == "creditCardSecurityCode") { - return AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE; - } - FT_LOG(Error) << "Not supported autofill hint : " << hint; - return std::nullopt; -} +} // namespace flutter diff --git a/flutter/shell/platform/tizen/tizen_autofill.h b/flutter/shell/platform/tizen/tizen_autofill.h index 56d247a..103ed92 100644 --- a/flutter/shell/platform/tizen/tizen_autofill.h +++ b/flutter/shell/platform/tizen/tizen_autofill.h @@ -13,6 +13,8 @@ #include +namespace flutter { + struct AutofillItem { autofill_hint_e hint_; bool sensitive_data_; @@ -28,15 +30,16 @@ class TizenAutofill { return instance; } - void RequestAutofill(std::vector hints, std::string id); + void RequestAutofill(const std::string& id, + const std::vector& hints); - void RegisterItem(std::string view_id, AutofillItem item); + void RegisterItem(const std::string& view_id, const AutofillItem& item); void StoreResponseItem(std::unique_ptr item) { response_items_.push_back(move(item)); } - void SetConnected(bool connected) { connected_ = connected; }; + void SetConnected(bool connected) { is_connected_ = connected; }; void SetOnPopup(std::function on_popup) { on_popup_ = on_popup; } @@ -44,7 +47,7 @@ class TizenAutofill { on_commit_ = on_commit; } - void OnCommit(std::string str) { on_commit_(str); } + void OnCommit(const std::string& str) { on_commit_(str); } void OnPopup() { on_popup_(); } @@ -57,13 +60,11 @@ class TizenAutofill { ~TizenAutofill(); - void Initailize(); - - std::optional ConvertAutofillHint(std::string hint); + void Initialize(); - bool connected_ = false; + bool is_connected_ = false; - bool initailzed_ = false; + bool is_initialized_ = false; autofill_h autofill_ = nullptr; @@ -74,4 +75,6 @@ class TizenAutofill { std::function on_commit_; }; -#endif +} // namespace flutter + +#endif // EMBEDDER_TIZEN_AUTOFILL_H_