[M108 Migration][Autofill] Introduce autofill fw interface 35/289135/5
authorAyush Kumar <ayush.k123@samsung.com>
Fri, 24 Feb 2023 05:04:43 +0000 (10:34 +0530)
committerBot Blink <blinkbot@samsung.com>
Sun, 5 Mar 2023 03:29:40 +0000 (03:29 +0000)
This change
1. Introduces interface for autofill fw in tizen.
2. Supports mockup for callbacks and APIs for SPASS feature for TV.
3. Refactors, enhances and fixes issue related to tizen autofill.

References : https://review.tizen.org/gerrit/269462

Change-Id: Ia91806470622bc4a1c2c5a2d917bf1babdb1e675
Signed-off-by: Ayush Kumar <ayush.k123@samsung.com>
91 files changed:
components/autofill/content/browser/content_autofill_driver_factory.cc
components/autofill/content/renderer/autofill_agent.cc
components/autofill/content/renderer/autofill_agent.h
components/autofill/content/renderer/form_tracker.cc
components/autofill/content/renderer/form_tracker.h
components/autofill/content/renderer/password_autofill_agent.cc
components/autofill/content/renderer/password_autofill_agent.h
components/autofill/content/renderer/password_form_conversion_utils.cc
components/autofill/core/browser/BUILD.gn
components/autofill/core/browser/browser_autofill_manager.cc
components/autofill/core/browser/payments/credit_card_save_manager.cc
components/autofill/core/browser/personal_data_manager.cc
components/autofill/core/common/autofill_switches.h
components/autofill/core/common/form_data.h
components/password_manager/core/browser/credential_manager_pending_request_task.cc
components/password_manager/core/browser/form_fetcher_impl.cc
components/password_manager/core/browser/form_fetcher_impl.h
components/password_manager/core/browser/http_password_store_migrator.cc
components/password_manager/core/browser/http_password_store_migrator.h
components/password_manager/core/browser/password_form_digest.cc
components/password_manager/core/browser/password_form_digest.h
components/password_manager/core/browser/password_form_manager.cc
components/password_manager/core/browser/password_manager.cc
components/password_manager/core/browser/password_manager_client.h
components/password_manager/core/browser/password_store.cc
components/password_manager/core/browser/password_store.h
components/password_manager/core/browser/password_store_backend.h
components/password_manager/core/browser/password_store_built_in_backend.cc
components/password_manager/core/browser/password_store_built_in_backend.h
components/password_manager/core/browser/password_store_interface.h
content/browser/renderer_host/render_frame_host_impl.cc
content/browser/renderer_host/render_process_host_impl.cc
content/browser/renderer_host/render_widget_host_impl.cc
content/browser/renderer_host/render_widget_host_impl.h
packaging/chromium-efl.spec
third_party/blink/public/mojom/widget/platform_widget.mojom
third_party/blink/public/web/web_autofill_client.h
third_party/blink/public/web/web_element.h
third_party/blink/public/web/web_local_frame.h
third_party/blink/renderer/core/exported/web_element.cc
third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
third_party/blink/renderer/core/frame/web_frame_widget_impl.h
third_party/blink/renderer/core/frame/web_local_frame_impl.cc
third_party/blink/renderer/core/frame/web_local_frame_impl.h
third_party/blink/renderer/platform/widget/widget_base.cc
third_party/blink/renderer/platform/widget/widget_base.h
third_party/blink/renderer/platform/widget/widget_base_client.h
tizen_src/build/BUILD.gn
tizen_src/build/config/BUILD.gn
tizen_src/build/config/tizen_features.gni
tizen_src/ewk/efl_integration/BUILD.gn
tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.cc
tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.h
tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.cc
tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.h
tizen_src/ewk/efl_integration/browser/autofill/autofill_login_request.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/autofill/autofill_login_request.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/autofill/autofill_request.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/autofill/autofill_request.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.cc
tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.h
tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc
tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h
tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.cc
tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.h
tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.cc
tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.h
tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.cc
tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.h
tizen_src/ewk/efl_integration/browser/webdata/web_data_service.cc
tizen_src/ewk/efl_integration/browser/webdata/web_data_service.h
tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.cc
tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.h
tizen_src/ewk/efl_integration/browser_context_efl.cc
tizen_src/ewk/efl_integration/content_browser_client_efl.cc
tizen_src/ewk/efl_integration/eweb_context.cc
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view_callbacks.h
tizen_src/ewk/efl_integration/private/ewk_autofill_profile_private.cc
tizen_src/ewk/efl_integration/private/ewk_autofill_profile_private.h
tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc
tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.h
tizen_src/ewk/efl_integration/public/ewk_autofill_profile.cc
tizen_src/ewk/efl_integration/public/ewk_context.cc
tizen_src/ewk/efl_integration/public/ewk_view.cc
tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc
tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc
tizen_src/ewk/efl_integration/web_contents_delegate_efl.h
tizen_src/ewk/efl_integration/web_contents_observer_efl.cc

index 528e832..939375e 100644 (file)
@@ -44,7 +44,7 @@ void BrowserDriverInitHook(AutofillClient* client,
                            ContentAutofillDriver* driver) {
   driver->set_autofill_manager(std::make_unique<BrowserAutofillManager>(
       driver, client, app_locale,
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
       AutofillManager::EnableDownloadManager(false)
 #else
       AutofillManager::EnableDownloadManager(true)
index e50083e..25fd3ef 100644 (file)
@@ -1179,6 +1179,12 @@ void AutofillAgent::JavaScriptChangedAutofilledValue(
   }
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void AutofillAgent::ForceResetLastInteractedElements() {
+  form_tracker_.ForceResetLastInteractedElements();
+}
+#endif
+
 void AutofillAgent::OnProvisionallySaveForm(
     const WebFormElement& form,
     const WebFormControlElement& element,
index 554a333..ae3063d 100644 (file)
@@ -216,6 +216,11 @@ class AutofillAgent : public content::RenderFrameObserver,
   void JavaScriptChangedAutofilledValue(
       const blink::WebFormControlElement& element,
       const blink::WebString& old_value) override;
+
+#if defined(TIZEN_AUTOFILL_FW)
+  void ForceResetLastInteractedElements() override;
+#endif
+
   void DidCompleteFocusChangeInFrame() override;
   void DidReceiveLeftMouseDownOrGestureTapInNode(
       const blink::WebNode& node) override;
index 16d5736..38c7295 100644 (file)
@@ -127,6 +127,12 @@ void FormTracker::FireProbablyFormSubmittedForTesting() {
   FireProbablyFormSubmitted();
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void FormTracker::ForceResetLastInteractedElements() {
+  ResetLastInteractedElements();
+}
+#endif
+
 void FormTracker::FormControlDidChangeImpl(
     const WebFormControlElement& element,
     Observer::ElementChangeSource change_source) {
index 248ccad..98b9382 100644 (file)
@@ -94,6 +94,9 @@ class FormTracker : public content::RenderFrameObserver,
   }
 
   void FireProbablyFormSubmittedForTesting();
+#if defined(TIZEN_AUTOFILL_FW)
+  void ForceResetLastInteractedElements();
+#endif
 
  private:
   FRIEND_TEST_ALL_PREFIXES(FormAutocompleteTest,
index 328c757..f37425c 100644 (file)
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/input/web_input_event.h"
+
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "base/command_line.h"
+#include "ewk/efl_integration/common/content_switches_efl.h"
+#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
+#include "third_party/blink/public/platform/web_application_type.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_frame_widget.h"
+#include "third_party/blink/public/web/web_widget.h"
+#endif
+
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/platform/web_vector.h"
 #include "third_party/blink/public/web/web_autofill_client.h"
@@ -74,6 +86,9 @@ using blink::WebNode;
 using blink::WebString;
 using blink::WebVector;
 using blink::WebView;
+#if BUILDFLAG(IS_TIZEN_TV)
+using blink::WebString;
+#endif
 
 namespace autofill {
 
@@ -99,6 +114,12 @@ const char kDebugAttributeForFieldSignature[] = "field_signature";
 const char kDebugAttributeForParserAnnotations[] = "pm_parser_annotation";
 const char kDebugAttributeForVisibility[] = "visibility_annotation";
 
+#if BUILDFLAG(IS_TIZEN_TV)
+// The words that frequently appear in attribute values of captcha elements.
+const char* const kCaptchaFeatures[] = {"captcha", "security", "code"};
+constexpr size_t kNumberOfCaptchaFeatures = std::size(kCaptchaFeatures);
+#define kSendEnterKeyTimeout 200
+#endif
 // Maps element names to the actual elements to simplify form filling.
 typedef std::map<std::u16string, WebInputElement> FormInputElementMap;
 
@@ -1438,6 +1459,13 @@ void PasswordAutofillAgent::OnProbablyFormSubmitted() {}
 // mojom::PasswordAutofillAgent:
 void PasswordAutofillAgent::SetPasswordFillData(
     const PasswordFormFillData& form_data) {
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " name: " << base::UTF16ToUTF8(form_data.name).c_str();
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " wait_for_username: " << form_data.wait_for_username;
+#endif
+
   std::unique_ptr<RendererSavePasswordProgressLogger> logger;
   if (logging_state_active_) {
     logger = std::make_unique<RendererSavePasswordProgressLogger>(
@@ -1475,12 +1503,20 @@ void PasswordAutofillAgent::SetPasswordFillData(
   // If wait_for_username is true, we don't want to initially fill the form
   // until the user types in a valid username.
   if (form_data.wait_for_username) {
+#if defined(TIZEN_AUTOFILL_FW)
+    // TODO(djmix.kim) : skip temporary for autofill form
+#else
     LogFirstFillingResult(form_data, FillingResult::kWaitForUsername);
     return;
+#endif
   }
 
   FillUserNameAndPassword(username_element, password_element, form_data,
                           logger.get());
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (SupportAutoLogin())
+    SubmitFormForAutoLogin(password_element);
+#endif
 }
 
 void PasswordAutofillAgent::SetLoggingState(bool active) {
@@ -1799,11 +1835,25 @@ bool PasswordAutofillAgent::FillUserNameAndPassword(
   WebInputElement main_element =
       is_single_username_fill ? username_element : password_element;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  WebFrame* cur_frame = main_element.GetDocument().GetFrame();
+  WebString bottom_frame_origin = cur_frame->GetSecurityOrigin().ToString();
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " bottom_frame_origin : " << bottom_frame_origin.Utf8().c_str()
+            << ", cur_frame->GetSecurityOrigin() : "
+            << cur_frame->GetSecurityOrigin().ToString().Utf8().c_str();
+  if (IsInCrossOriginIframeOrEmbeddedFrame(main_element)) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__
+              << " daum login issue, skip temporary";
+    // TODO(djmix.kim) : skip temporary for daum login issue
+  }
+#else
   if (IsInCrossOriginIframeOrEmbeddedFrame(main_element)) {
     LogMessage(logger, Logger::STRING_FAILED_TO_FILL_INTO_IFRAME);
     LogFirstFillingResult(fill_data, FillingResult::kBlockedByFrameHierarchy);
     return false;
   }
+#endif
 
   // Don't fill username if password can't be set.
   if (!IsElementEditable(main_element)) {
@@ -1896,6 +1946,11 @@ bool PasswordAutofillAgent::FillUserNameAndPassword(
         (username_element.Value().IsEmpty() ||
          username_element.GetAutofillState() != WebAutofillState::kNotFilled ||
          prefilled_placeholder_username)) {
+#if defined(TIZEN_AUTOFILL_FW)
+      // We fill username and password directly
+      FillField(&username_element, username);
+    }
+#else
       AutofillField(username, username_element);
       if (prefilled_placeholder_username) {
         LogPrefilledUsernameFillOutcome(
@@ -1903,12 +1958,17 @@ bool PasswordAutofillAgent::FillUserNameAndPassword(
                 kPrefilledPlaceholderUsernameOverridden);
       }
     }
+#endif
     if (logger)
       logger->LogElementName(Logger::STRING_USERNAME_FILLED, username_element);
   }
 
   if (!is_single_username_fill) {
+#if defined(TIZEN_AUTOFILL_FW)
+    FillPasswordFieldAndSave(&password_element, password);
+#else
     AutofillField(password, password_element);
+#endif
     if (logger)
       logger->LogElementName(Logger::STRING_PASSWORD_FILLED, password_element);
   }
@@ -2221,4 +2281,124 @@ void PasswordAutofillAgent::NotifyPasswordManagerAboutClearedForm(
   }
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void PasswordAutofillAgent::SendEnterKeyBoardEvent() {
+  if (!render_frame())
+    return;
+  blink::WebView* web_view = render_frame()->GetWebView();
+  if (!web_view)
+    return;
+  blink::WebWidget* widget = web_view->MainFrameWidget();
+
+  LOG(INFO) << "[Autofill] - " << __FUNCTION__;
+  blink::WebKeyboardEvent keyboard_event;
+  keyboard_event.windows_key_code = ui::VKEY_RETURN;
+  keyboard_event.SetModifiers(blink::WebInputEvent::kIsKeyPad);
+  keyboard_event.text[0] = ui::VKEY_RETURN;
+  keyboard_event.SetType(blink::WebInputEvent::Type::kKeyDown);
+  widget->HandleInputEvent(
+      blink::WebCoalescedInputEvent(keyboard_event, ui::LatencyInfo()));
+  keyboard_event.SetType(blink::WebInputEvent::Type::kKeyUp);
+  widget->HandleInputEvent(
+      blink::WebCoalescedInputEvent(keyboard_event, ui::LatencyInfo()));
+}
+
+// Removes some characters from attribute value.
+void ClearAttributeValue(std::string* value) {
+  value->erase(std::remove_if(value->begin(), value->end(),
+                              [](char x) { return x == '-' || x == '_'; }),
+               value->end());
+}
+// Find |features| in |element|'s attribute values. Returns true if at least one
+// text feature was found.
+bool FindTextFeaturesForClass(const blink::WebElement& element,
+                              const char* const features[],
+                              size_t number_of_features) {
+  DCHECK(features);
+
+  for (unsigned i = 0; i < element.AttributeCount(); ++i) {
+    std::string filtered_value =
+        base::ToLowerASCII(element.AttributeValue(i).Utf8());
+    ClearAttributeValue(&filtered_value);
+
+    if (filtered_value.empty())
+      continue;
+    for (size_t j = 0; j < number_of_features; ++j) {
+      if (filtered_value.find(features[j]) != std::string::npos)
+        return true;
+    }
+  }
+  return false;
+}
+
+// Returns true if at least one captcha feature was found in |element|'s
+// attribute values.
+bool IsCaptchaInput(const blink::WebInputElement& element) {
+  return FindTextFeaturesForClass(element, kCaptchaFeatures,
+                                  kNumberOfCaptchaFeatures);
+}
+// Finds <img>'s inside |form| and checks if <img>'s attributes contains captcha
+// text features. Returns true, if at least one occurrence was found.
+bool FindCaptchaInImgElements(const blink::WebElement& form) {
+  static const base::NoDestructor<WebString> wrapper("img");
+  const WebString& kImageTag = *wrapper;
+
+  blink::WebElementCollection img_elements =
+      form.GetElementsByHTMLTagName(kImageTag);
+  for (blink::WebElement element = img_elements.FirstItem(); !element.IsNull();
+       element = img_elements.NextItem()) {
+    if (!form_util::IsWebElementVisible(element))
+      continue;
+
+    if (FindTextFeaturesForClass(element, kCaptchaFeatures,
+                                 kNumberOfCaptchaFeatures)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void PasswordAutofillAgent::SubmitFormForAutoLogin(
+    blink::WebInputElement& password_input) {
+  LOG(INFO) << "[Autofill] - " << __FUNCTION__;
+  if (IsCaptchaInput(password_input)) {
+    LOG(INFO) << "[Autofill] - " << __FUNCTION__
+              << " Page include captcha input, do not autologin";
+    return;
+  }
+  if (FindCaptchaInImgElements(password_input.Form())) {
+    LOG(INFO) << "[Autofill] - " << __FUNCTION__
+              << " Page include captcha image, do not autologin";
+    return;
+  }
+  // FIXME: sometimes focus is on other field but login form,
+  // it will cause key event send to wrong element.
+  password_input.Focus();
+  // Attention: if password_input element is not focusable at the time of
+  // calling Focus(), it will still be unfocused after Focus() is returned.
+
+  // TODO(daoning.ren): this is workaround solution for google.com
+  // there is delay page switch during login, key event will send
+  // before page switch, so make a delay here
+  render_frame()
+      ->GetTaskRunner(blink::TaskType::kInternalUserInteraction)
+      ->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&PasswordAutofillAgent::SendEnterKeyBoardEvent,
+                         base::Unretained(this)),
+          base::Milliseconds(kSendEnterKeyTimeout));
+}
+
+bool PasswordAutofillAgent::SupportAutoLogin() {
+  // There are 2 browser types from Tizen5.5:
+  //  org.tizen.browser,  com.samsung.tv.knox-browser
+  // Only org.tizen.browser app need AutoLogin behavior according to their spec.
+  // The latter just wants Autofill.
+  const std::string tizen_app_id =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kTizenAppId);
+  return tizen_app_id == "org.tizen.browser";
+}
+#endif
+
 }  // namespace autofill
index 63a6ff4..cb93e85 100644 (file)
@@ -504,6 +504,21 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
   void NotifyPasswordManagerAboutClearedForm(
       const blink::WebFormElement& cleared_form);
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  // Returns if the word 'captcha' is present in the markup of any of the nodes
+  // under the given node.
+  bool CheckMarkupForCaptcha(blink::WebFormElement element);
+
+  // Attemps to do autologin
+  void SubmitFormForAutoLogin(blink::WebInputElement& password_input);
+
+  // Attempts to send enterkeydown events to blink
+  void SendEnterKeyBoardEvent();
+
+  // Return whether we need to support autologin.
+  bool SupportAutoLogin();
+#endif
+
   // The logins we have filled so far with their associated info.
   WebInputToPasswordInfoMap web_input_to_password_info_;
   // A (sort-of) reverse map to |web_input_to_password_info_|.
index 86eef13..4254c09 100644 (file)
@@ -116,6 +116,17 @@ bool IsGaiaWithSkipSavePasswordForm(const blink::WebFormElement& form) {
   return should_skip_password == "1";
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+// Returns the PasswordContents reflecting the contents of |fields|.
+bool HasPasswordContents(const std::vector<FormFieldData>& fields) {
+  for (const FormFieldData& field : fields) {
+    if (field.form_control_type == "password")
+      return true;
+  }
+  return false;
+}
+#endif
+
 std::unique_ptr<FormData> CreateFormDataFromWebForm(
     const WebFormElement& web_form,
     const FieldDataManager* field_data_manager,
@@ -139,12 +150,23 @@ std::unique_ptr<FormData> CreateFormDataFromWebForm(
                                 form_data.get(), nullptr /* FormFieldData */)) {
     return nullptr;
   }
+
+#if defined(TIZEN_AUTOFILL_FW)
+  if (!HasPasswordContents(form_data->fields)) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << ", not a password form";
+    return nullptr;
+  }
+#endif
+
   form_data->username_predictions =
       GetUsernamePredictions(control_elements.ReleaseVector(), *form_data,
                              username_detector_cache, web_form);
   form_data->button_titles = form_util::GetButtonTitles(
       web_form, web_form.GetDocument(), button_titles_cache);
 
+#if defined(TIZEN_AUTOFILL_FW)
+  form_data->title = web_form.GetDocument().Title().Utf8();
+#endif
   return form_data;
 }
 
@@ -172,11 +194,21 @@ std::unique_ptr<FormData> CreateFormDataFromUnownedInputElements(
     return nullptr;
   }
 
+#if defined(TIZEN_AUTOFILL_FW)
+  if (!HasPasswordContents(form_data->fields)) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << ", not a password form";
+    return nullptr;
+  }
+#endif
+
   form_data->username_predictions = GetUsernamePredictions(
       control_elements, *form_data, username_detector_cache, WebFormElement());
   form_data->button_titles = form_util::GetButtonTitles(
       WebFormElement(), frame.GetDocument(), button_titles_cache);
 
+#if defined(TIZEN_AUTOFILL_FW)
+  form_data->title = frame.GetDocument().Title().Utf8();
+#endif
   return form_data;
 }
 
index 444cae5..56c06e5 100644 (file)
@@ -500,6 +500,19 @@ static_library("browser") {
 
   defines = [ "CHROME_VERSION_MAJOR=" + chrome_version_major ]
 
+  if (tizen_autofill_fw) {
+    configs += [
+      "//tizen_src/build:ecore-evas",
+      "//tizen_src/build:libecore-evas",
+      "//tizen_src/build:capi-ui-autofill",
+      "//tizen_src/build:libcapi-ui-autofill",
+      "//tizen_src/build:capi-ui-autofill-common",
+      "//tizen_src/build:libcapi-ui-autofill-common",
+      "//tizen_src/build:capi-ui-autofill-service",
+      "//tizen_src/build:libcapi-ui-autofill-service",
+    ]
+  }
+
   configs += [ "//build/config:precompiled_headers" ]
 
   public_deps = [
index 9712866..cff3f52 100644 (file)
@@ -830,6 +830,14 @@ void BrowserAutofillManager::OnFormSubmittedImpl(const FormData& form,
     credit_card_form_event_logger_->OnFormSubmitted(sync_state_,
                                                     *submitted_form);
   }
+
+#if defined(TIZEN_AUTOFILL)
+  if (!client()->GetFormDataImporter()) {
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__
+               << " FormDataImporter is invalid";
+    return;
+  }
+#endif
 }
 
 bool BrowserAutofillManager::MaybeStartVoteUploadProcess(
index 9c0ef61..d13ff1c 100644 (file)
@@ -309,6 +309,13 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
 }
 
 bool CreditCardSaveManager::IsCreditCardUploadEnabled() {
+#if defined(TIZEN_AUTOFILL_FW)
+  if (!personal_data_manager_) {
+    LOG(INFO) << "Autofill " << __FUNCTION__
+              << "  Invalid personal_data_manager_";
+    return false;
+  }
+#endif
 #if BUILDFLAG(IS_IOS)
   // If observer_for_testing_ is set, assume we are in a browsertest and
   // credit card upload should be enabled by default.
index b056cd0..102769b 100644 (file)
@@ -1033,7 +1033,7 @@ void PersonalDataManager::AddOfferDataForTest(
 void PersonalDataManager::
     RemoveAutofillProfileByGUIDAndBlankCreditCardReference(
         const std::string& guid) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   // TODO(djmix.kim) : This is a temporary solution for tct.
   // It will be removed after integrating autofill_profile_validator_factory.
   database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
index 2e5cf7c..f9c2030 100644 (file)
@@ -20,9 +20,9 @@ extern const char kShowAutofillTypePredictions[];
 extern const char kShowAutofillSignatures[];
 extern const char kWalletServiceUseSandbox[];
 
-// As of today TIZEN_AUTOFILL_SUPPORT is restricted to
+// As of today TIZEN_AUTOFILL is restricted to
 // tizen_src/ewk/efl_integration only. Move this switch under
-// TIZEN_AUTOFILL_SUPPORT when possible.
+// TIZEN_AUTOFILL when possible.
 #if BUILDFLAG(IS_EFL)
 extern const char kDisableAutofill[];
 #endif
index 2f23b0d..1fef743 100644 (file)
@@ -276,6 +276,9 @@ struct FormData {
 #if BUILDFLAG(IS_IOS)
   std::string frame_id;
 #endif
+#if defined(TIZEN_AUTOFILL_FW)
+  std::string title;
+#endif
 };
 
 // Whether any of the fields in |form| is a non-empty password field.
index da43e1a..d74fcfa 100644 (file)
@@ -168,7 +168,11 @@ void CredentialManagerPendingRequestTask::OnGetPasswordStoreResultsFrom(
   if (results.empty() && origin_.scheme() == url::kHttpsScheme) {
     // Try to migrate the HTTP passwords and process them later.
     http_migrators_[store] = std::make_unique<HttpPasswordStoreMigrator>(
-        origin_, store, delegate_->client()->GetNetworkContext(), this);
+        origin_, store, delegate_->client()->GetNetworkContext(),
+#if defined(TIZEN_AUTOFILL_FW)
+        delegate_->client(),
+#endif
+        this);
     return;
   }
   AggregatePasswordStoreResults(std::move(results));
index f3827e8..702d49a 100644 (file)
@@ -122,8 +122,17 @@ void FormFetcherImpl::Fetch() {
     wait_counter_++;
 
   state_ = State::WAITING;
+#if defined(TIZEN_AUTOFILL_FW)
+  profile_password_store->GetLogins(
+      form_digest_, weak_ptr_factory_.GetWeakPtr(), skip_checking_autofill_,
+      client_->GetWebview());
+
+  skip_checking_autofill_ = false;
+#else
+
   profile_password_store->GetLogins(form_digest_,
                                     weak_ptr_factory_.GetWeakPtr());
+#endif
   if (account_password_store)
     account_password_store->GetLogins(form_digest_,
                                       weak_ptr_factory_.GetWeakPtr());
@@ -216,6 +225,10 @@ std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() {
   // then it was done by |this| already.
   auto result = std::make_unique<FormFetcherImpl>(form_digest_, client_, false);
 
+#if defined(TIZEN_AUTOFILL_FW)
+  result->skip_checking_autofill_ = true;
+#endif
+
   if (state_ != State::NOT_WAITING) {
     // There are no store results to copy, trigger a Fetch on the clone instead.
     result->Fetch();
@@ -326,7 +339,11 @@ void FormFetcherImpl::OnGetPasswordStoreResultsOrErrorFrom(
       form_digest_.url.SchemeIs(url::kHttpsScheme)) {
     http_migrators_[store] = std::make_unique<HttpPasswordStoreMigrator>(
         url::Origin::Create(form_digest_.url), store,
-        client_->GetNetworkContext(), this);
+        client_->GetNetworkContext(),
+#if defined(TIZEN_AUTOFILL_FW)
+        client_,
+#endif
+        this);
     // The migrator will call us back at ProcessMigratedForms().
     return;
   }
index 7755207..80f865b 100644 (file)
@@ -94,6 +94,10 @@ class FormFetcherImpl : public FormFetcher,
   // List of insecure credentials for the current domain.
   std::vector<std::unique_ptr<PasswordForm>> insecure_credentials_;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  bool skip_checking_autofill_ = false;
+#endif
+
   // Indicates whether HTTP passwords should be migrated to HTTPS. This is
   // always false for non HTML forms.
   const bool should_migrate_http_passwords_;
index f041604..d8b60b0 100644 (file)
 #include "url/gurl.h"
 #include "url/url_constants.h"
 
+#if defined(TIZEN_AUTOFILL_FW)
+#include "components/password_manager/core/browser/password_manager_client.h"
+#endif
+
 namespace password_manager {
 
 namespace {
@@ -39,6 +43,9 @@ HttpPasswordStoreMigrator::HttpPasswordStoreMigrator(
     const url::Origin& https_origin,
     PasswordStoreInterface* store,
     network::mojom::NetworkContext* network_context,
+#if defined(TIZEN_AUTOFILL_FW)
+    const PasswordManagerClient* client,
+#endif
     Consumer* consumer)
     : store_(store), consumer_(consumer) {
   DCHECK(store_);
@@ -52,8 +59,12 @@ HttpPasswordStoreMigrator::HttpPasswordStoreMigrator(
                           http_origin.DeprecatedGetOriginAsURL().spec(),
                           http_origin);
   http_origin_domain_ = url::Origin::Create(http_origin);
-  store_->GetLogins(form, weak_ptr_factory_.GetWeakPtr());
-
+  store_->GetLogins(form, weak_ptr_factory_.GetWeakPtr()
+#if defined(TIZEN_AUTOFILL_FW)
+                              ,
+                    false, client->GetWebview()
+#endif
+  );
   PostHSTSQueryForHostAndNetworkContext(
       https_origin, network_context,
       base::BindOnce(&OnHSTSQueryResultHelper, weak_ptr_factory_.GetWeakPtr()));
index 8e41538..33b0461 100644 (file)
@@ -20,6 +20,10 @@ namespace password_manager {
 class PasswordStoreInterface;
 struct PasswordForm;
 
+#if defined(TIZEN_AUTOFILL_FW)
+class PasswordManagerClient;
+#endif
+
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
 //
@@ -58,6 +62,9 @@ class HttpPasswordStoreMigrator : public PasswordStoreConsumer {
   HttpPasswordStoreMigrator(const url::Origin& https_origin,
                             PasswordStoreInterface* store,
                             network::mojom::NetworkContext* network_context,
+#if defined(TIZEN_AUTOFILL_FW)
+                            const PasswordManagerClient* client,
+#endif
                             Consumer* consumer);
 
   HttpPasswordStoreMigrator(const HttpPasswordStoreMigrator&) = delete;
index 9947fda..e0c5130 100644 (file)
@@ -4,6 +4,10 @@
 
 #include "components/password_manager/core/browser/password_form_digest.h"
 
+#if defined(TIZEN_AUTOFILL_FW)
+#include "base/strings/utf_string_conversions.h"
+#endif
+
 namespace password_manager {
 PasswordFormDigest::PasswordFormDigest(PasswordForm::Scheme new_scheme,
                                        const std::string& new_signon_realm,
@@ -11,7 +15,15 @@ PasswordFormDigest::PasswordFormDigest(PasswordForm::Scheme new_scheme,
     : scheme(new_scheme), signon_realm(new_signon_realm), url(new_url) {}
 
 PasswordFormDigest::PasswordFormDigest(const PasswordForm& form)
-    : scheme(form.scheme), signon_realm(form.signon_realm), url(form.url) {}
+    : scheme(form.scheme),
+      signon_realm(form.signon_realm),
+      url(form.url)
+#if defined(TIZEN_AUTOFILL_FW)
+      ,
+      username(base::UTF16ToUTF8(form.username_value))
+#endif
+{
+}
 
 PasswordFormDigest::PasswordFormDigest(const autofill::FormData& form)
     : scheme(PasswordForm::Scheme::kHtml),
index bf5490e..aa42105 100644 (file)
@@ -33,6 +33,9 @@ struct PasswordFormDigest {
   PasswordForm::Scheme scheme;
   std::string signon_realm;
   GURL url;
+#if defined(TIZEN_AUTOFILL_FW)
+  std::string username;
+#endif
 };
 
 // For testing only.
index 39cb192..ed5f73a 100644 (file)
@@ -174,6 +174,9 @@ PasswordFormManager::PasswordFormManager(
   // saving are supported.
   if (owned_form_fetcher_ &&
       !observed_form()->is_gaia_with_skip_save_password_form) {
+#if defined(TIZEN_AUTOFILL_FW)
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << " call Fetch()";
+#endif
     owned_form_fetcher_->Fetch();
 
     WebAuthnCredentialsDelegate* delegate =
index bdf2d73..ec83f6d 100644 (file)
 using autofill::ACCOUNT_CREATION_PASSWORD;
 using autofill::FieldDataManager;
 using autofill::FieldRendererId;
+
+#if defined(TIZEN_AUTOFILL_FW)
+#include "components/autofill/core/common/form_field_data.h"
+#include "tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.h"
+#endif
+
 using autofill::FormData;
 using autofill::FormRendererId;
 using autofill::FormStructure;
@@ -75,6 +81,10 @@ using password_manager::metrics_util::GaiaPasswordHashChange;
 namespace password_manager {
 
 namespace {
+#if defined(TIZEN_AUTOFILL_FW)
+const char kDefaultUserElement[] = "email";
+const char kDefaultPassElement[] = "pass";
+#endif
 
 // Shorten the name to spare line breaks. The code provides enough context
 // already.
@@ -927,6 +937,9 @@ bool PasswordManager::IsAutomaticSavePromptAvailable() {
     if (logger) {
       logger->LogMessage(Logger::STRING_NO_PROVISIONAL_SAVE_MANAGER);
     }
+#if defined(TIZEN_AUTOFILL_FW)
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << " No submitted_manager";
+#endif
     return false;
   }
 
@@ -953,6 +966,9 @@ bool PasswordManager::ShouldBlockPasswordForSameOriginButDifferentScheme(
 void PasswordManager::OnPasswordFormsRendered(
     password_manager::PasswordManagerDriver* driver,
     const std::vector<FormData>& visible_forms_data) {
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__;
+#endif
   CreatePendingLoginManagers(driver, visible_forms_data);
   std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
   if (password_manager_util::IsLoggingActive(client_)) {
@@ -1041,6 +1057,13 @@ void PasswordManager::OnPasswordFormsRendered(
 }
 
 void PasswordManager::OnLoginSuccessful() {
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__;
+  auto webview = client_->GetWebview();
+  if (!webview)
+    return;
+  autofill::AutofillRequestManager::GetInstance()->OnLogin(webview);
+#endif
   if (client_->IsAutofillAssistantUIVisible()) {
     // Suppress prompts while Autofill Assistant UI is shown.
     return;
@@ -1114,6 +1137,68 @@ void PasswordManager::OnLoginSuccessful() {
       "PasswordManager.SuccessfulLoginHappened",
       submitted_manager->GetSubmittedForm()->url.SchemeIsCryptographic());
 
+#if defined(TIZEN_AUTOFILL_FW)
+  FormData form = submitted_manager->GetSubmittedForm()->form_data;
+
+  for (size_t i = 0; i < form.fields.size(); i++) {
+    if (form.fields[i].is_autofilled) {
+      LOG(ERROR) << "[Autofill] " << __FUNCTION__ << "\t label : "
+                 << base::UTF16ToUTF8(form.fields[i].label).c_str();
+      LOG(ERROR) << "[Autofill] " << __FUNCTION__
+                 << " is_autofilled! do not send commit request";
+
+      owned_submitted_form_manager_.reset();
+      return;
+    }
+  }
+
+  std::string user_element = base::UTF16ToUTF8(
+      submitted_manager->GetSubmittedForm()->username_element);
+  std::string user_value =
+      base::UTF16ToUTF8(submitted_manager->GetSubmittedForm()->username_value);
+  std::string pass_element = base::UTF16ToUTF8(
+      submitted_manager->GetSubmittedForm()->password_element);
+  std::string pass_value =
+      base::UTF16ToUTF8(submitted_manager->GetSubmittedForm()->password_value);
+
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " user_element : " << user_element.c_str()
+            << ", user_value : " << user_value.c_str()
+            << ", pass_element : " << pass_element.c_str();
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " origin : "
+            << submitted_manager->GetSubmittedForm()->url.spec().c_str()
+            << ", title : " << form.title.c_str();
+
+  if (user_element.empty())
+    user_element = kDefaultUserElement;
+
+  if (pass_element.empty())
+    pass_element = kDefaultPassElement;
+
+  GURL origin = submitted_manager->GetSubmittedForm()->url;
+
+  // FIXME. Current autofill mechanism is to save what user enters originally in
+  // account name field into db. On the other hand, in google login scenes, user
+  // is allowed to enter only the text before '@'. Afterwards, when user selects
+  // old account to login, string passed to db will be "***@gmail.com", instead
+  // of "***". Since autofill code only knows "***", autofill action will not be
+  // triggered. So we append domain name here.
+  if (origin.host() == "accounts.google.com" &&
+      user_value.find("@") == std::string::npos) {
+    LOG(ERROR)
+        << "[Autofill] user has not input suffix, will append @gmail.com";
+    user_value.append("@gmail.com");
+  }
+
+  autofill::AutofillRequestManager::GetInstance()->CommitAutofill(
+      webview, user_element, user_value, pass_element, pass_value, origin,
+      form.title.c_str());
+
+  owned_submitted_form_manager_.reset();
+
+  return;
+#endif
+
   // If the form is eligible only for saving fallback, it shouldn't go here.
   DCHECK(!submitted_manager->GetPendingCredentials().only_for_fallback);
 
index 1b6bf55..ba0800c 100644 (file)
@@ -425,6 +425,9 @@ class PasswordManagerClient {
 
   // Records a Chrome Sync event that GAIA password reuse was detected.
   virtual void LogPasswordReuseDetectedEvent() = 0;
+#if defined(TIZEN_AUTOFILL_FW)
+  virtual void* GetWebview() const { return nullptr; }
+#endif
 
   // If the feature is enabled send an event to the enterprise reporting
   // connector server indicating that the user signed in to a website.
index 6c6bc4c..755039f 100644 (file)
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/sync/model/proxy_model_type_controller_delegate.h"
 
+#if defined(TIZEN_AUTOFILL_FW)
+#include "base/synchronization/waitable_event.h"
+#include "tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.h"
+#endif
+
 namespace password_manager {
 
 namespace {
@@ -237,7 +242,13 @@ void PasswordStore::Unblocklist(const PasswordFormDigest& form_digest,
 }
 
 void PasswordStore::GetLogins(const PasswordFormDigest& form,
-                              base::WeakPtr<PasswordStoreConsumer> consumer) {
+                              base::WeakPtr<PasswordStoreConsumer> consumer
+#if defined(TIZEN_AUTOFILL_FW)
+                              ,
+                              bool skip_checking_autofill,
+                              void* view
+#endif
+) {
   DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   if (!backend_)
     return;  // Once the shutdown started, ignore new requests.
@@ -262,11 +273,53 @@ void PasswordStore::GetLogins(const PasswordFormDigest& form,
   // `request_handler` that there are no affiliated logins.
   request_handler->AffiliatedLoginsClosure().Run({});
 
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] PasswordStore::GetLogins, signon_realm: "
+            << form.signon_realm << ", origin: " << form.url.spec()
+            << ", username: " << form.username << ", view: " << view
+            << ", skip_checking_autofill: " << skip_checking_autofill;
+  if (!view)
+    return;
+
+  if (!skip_checking_autofill) {
+    if (backend_) {
+      backend_->PostTaskToBackgroundTaskRunner(
+          base::BindOnce(&PasswordStore::CheckAutofillData, this, form, view,
+                        request_handler->LoginsForFormClosure()));
+    }
+  } else {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << " with view " << view
+              << " skip to check autofill";
+    InjectAffiliationAndBrandingInformation(
+        request_handler->LoginsForFormClosure(),
+        std::vector<std::unique_ptr<PasswordForm>>());
+  }
+#else
   // And request the regular logins for `form`.
   backend_->FillMatchingLoginsAsync(request_handler->LoginsForFormClosure(),
                                     FormSupportsPSL(form), {form});
+#endif
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void PasswordStore::CheckAutofillData(const PasswordFormDigest& form,
+                                      void* view,
+                                      LoginsOrErrorReply callback) {
+  base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+                           base::WaitableEvent::InitialState::NOT_SIGNALED);
+  autofill::AutofillRequestManager::GetInstance()->CheckAutofillData(
+      view, &done, form.signon_realm, form.url, form.username);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " with view " << view
+            << " wait start!";
+  done.Wait();
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " with view " << view
+            << " wait end!";
+  InjectAffiliationAndBrandingInformation(
+      std::move(callback),
+      autofill::AutofillRequestManager::GetInstance()->GetResult(view));
+}
+#endif
+
 void PasswordStore::GetAutofillableLogins(
     base::WeakPtr<PasswordStoreConsumer> consumer) {
   DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
index 1b639a4..37c1076 100644 (file)
@@ -109,10 +109,23 @@ class PasswordStore : public PasswordStoreInterface {
       const PasswordFormDigest& form_digest,
       base::OnceClosure completion = base::NullCallback()) override;
   void GetLogins(const PasswordFormDigest& form,
-                 base::WeakPtr<PasswordStoreConsumer> consumer) override;
+                 base::WeakPtr<PasswordStoreConsumer> consumer
+#if defined(TIZEN_AUTOFILL_FW)
+                 ,
+                 bool skip_checking_autofill = false,
+                 void* view = nullptr
+#endif
+                 ) override;
   void GetAutofillableLogins(
       base::WeakPtr<PasswordStoreConsumer> consumer) override;
   void GetAllLogins(base::WeakPtr<PasswordStoreConsumer> consumer) override;
+
+#if defined(TIZEN_AUTOFILL_FW)
+  void CheckAutofillData(const PasswordFormDigest& form,
+                         void* view,
+                         LoginsOrErrorReply callback);
+#endif
+
   void GetAllLoginsWithAffiliationAndBrandingInformation(
       base::WeakPtr<PasswordStoreConsumer> consumer) override;
   void AddObserver(Observer* observer) override;
index 8719de2..6d44553 100644 (file)
@@ -140,6 +140,10 @@ class PasswordStoreBackend {
   // Propagates sync initialization event.
   virtual void OnSyncServiceInitialized(syncer::SyncService* sync_service) = 0;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  virtual void PostTaskToBackgroundTaskRunner(base::OnceClosure task);
+#endif
+
   // Factory function for creating the backend. The Local backend requires the
   // provided `login_db_path` for storage and Android backend for migration
   // purposes.
index 2b67979..fb1c44b 100644 (file)
@@ -347,4 +347,11 @@ void PasswordStoreBuiltInBackend::RemoveFieldInfoByTime(
       std::move(completion));
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void PasswordStoreBuiltInBackend::PostTaskToBackgroundTaskRunner(
+    base::OnceClosure task) {
+  background_task_runner_->PostTask(FROM_HERE, std::move(task));
+}
+#endif
+
 }  // namespace password_manager
index f98ec1c..71aa363 100644 (file)
@@ -104,6 +104,10 @@ class PasswordStoreBuiltInBackend : public PasswordStoreBackend,
                              base::Time remove_end,
                              base::OnceClosure completion) override;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  void PostTaskToBackgroundTaskRunner(base::OnceClosure task) override;
+#endif
+
   // Ensures that all methods are called on the main sequence.
   SEQUENCE_CHECKER(sequence_checker_);
 
index b366f7c..12c3f70 100644 (file)
@@ -124,7 +124,13 @@ class PasswordStoreInterface : public RefcountedKeyedService {
   // completion.
   // TODO(crbug.com/1217070): Use a smart pointer for consumer.
   virtual void GetLogins(const PasswordFormDigest& form,
-                         base::WeakPtr<PasswordStoreConsumer> consumer) = 0;
+                         base::WeakPtr<PasswordStoreConsumer> consumer
+#if defined(TIZEN_AUTOFILL_FW)
+                         ,
+                         bool skip_checking_autofill = false,
+                         void* view = nullptr
+#endif
+                         ) = 0;
 
   // Gets the complete list of non-blocklist PasswordForms.`consumer` will be
   // notified on completion.
index d805754..cf3daa1 100644 (file)
 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #endif
 
+#if defined(TIZEN_AUTOFILL)
+#include "components/autofill/content/common/mojom/autofill_driver.mojom.h"
+#include "tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.h"
+#endif
+
 namespace features {
 BASE_FEATURE(kDisableFrameNameUpdateOnNonCurrentRenderFrameHost,
              "DisableFrameNameUpdateOnNonCurrentRenderFrameHost",
@@ -9631,6 +9636,18 @@ void RenderFrameHostImpl::SetUpMojoConnection() {
       ->RegisterAssociatedInterfaceBindersForRenderFrameHost(
           *this, *associated_registry_);
 
+#if defined(TIZEN_AUTOFILL)
+  associated_registry_->AddInterface<autofill::mojom::PasswordManagerDriver>(
+      base::BindRepeating(
+          [](RenderFrameHostImpl* impl,
+             mojo::PendingAssociatedReceiver<
+                 autofill::mojom::PasswordManagerDriver> receiver) {
+            password_manager::PasswordManagerClientEfl::BindReceiver(
+                std::move(receiver), impl);
+          },
+          base::Unretained(this)));
+#endif
+
   mojo::PendingRemote<service_manager::mojom::InterfaceProvider>
       remote_interfaces;
   GetMojomFrameInRenderer()->GetInterfaceProvider(
index 64796df..e5affe2 100644 (file)
 #define MAYBEVLOG DVLOG
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "tizen_src/ewk/efl_integration/common/content_switches_efl.h"
+#endif
+
 namespace content {
 
 namespace {
@@ -3443,6 +3447,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
     switches::kDiscardableMemoryLimit,
     switches::kDiscardableMemoryPurgeDelay,
 #endif
+#if BUILDFLAG(IS_TIZEN_TV)
+    switches::kTizenAppId,
+#endif
   };
   renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
                                  std::size(kSwitchNames));
index 01636ff..93e943a 100644 (file)
@@ -1070,6 +1070,10 @@ void RenderWidgetHostImpl::OnGetSelectionRect(const gfx::Rect& rect) {
     return;
   view_->OnSelectionRectReceived(rect);
 }
+
+void RenderWidgetHostImpl::ResetLastInteractedElements() {
+  blink_widget_->ResetLastInteractedElements();
+}
 #endif
 
 #if defined(TIZEN_VIDEO_HOLE)
index 514de59..8600050 100644 (file)
@@ -459,6 +459,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
   void SelectFocusedLink();
   void RequestSelectionRect();
   void OnGetSelectionRect(const gfx::Rect& rect);
+  void ResetLastInteractedElements();
 #endif
 
 #if defined(TIZEN_VIDEO_HOLE)
index 38a8e7a..f803e29 100755 (executable)
@@ -75,6 +75,9 @@ BuildRequires: pkgconfig(capi-system-device)
 BuildRequires: pkgconfig(capi-system-info)
 BuildRequires: pkgconfig(capi-system-sensor)
 BuildRequires: pkgconfig(capi-system-system-settings)
+BuildRequires: pkgconfig(capi-ui-autofill)
+BuildRequires: pkgconfig(capi-ui-autofill-common)
+BuildRequires: pkgconfig(capi-ui-autofill-service)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(ecore-evas)
index a923c1c..0cec2c3 100644 (file)
@@ -133,6 +133,10 @@ interface Widget {
   SetLongPollingGlobalTimeout(uint64 timeout);
 
   [EnableIf=is_efl]
+  ResetLastInteractedElements();
+
+
+  [EnableIf=is_efl]
   PrintToPdf(uint32 width, uint32 height, mojo_base.mojom.FilePath filename);
 
   [EnableIf=tizen_video_hole]
index c57df43..a18cfb8 100644 (file)
@@ -69,6 +69,10 @@ class WebAutofillClient {
       const WebFormControlElement& element,
       const WebString& old_value) {}
 
+#if defined(TIZEN_AUTOFILL_FW)
+  virtual void ForceResetLastInteractedElements() {}
+#endif
+
   virtual void DidCompleteFocusChangeInFrame() {}
   virtual void DidReceiveLeftMouseDownOrGestureTapInNode(const WebNode&) {}
 
index ee97a96..b88d7ce 100644 (file)
@@ -140,6 +140,10 @@ class BLINK_EXPORT WebElement : public WebNode {
   // of the <param> URL functionality.
   void UseCountParamUrlUsageIfNeeded(bool is_pdf) const;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  BLINK_EXPORT void Focus();
+#endif
+
 #if INSIDE_BLINK
   WebElement(Element*);
   WebElement& operator=(Element*);
index 6ec3917..285229a 100644 (file)
@@ -193,6 +193,9 @@ class BLINK_EXPORT WebLocalFrame : public WebFrame {
 
   virtual void SetAutofillClient(WebAutofillClient*) = 0;
   virtual WebAutofillClient* AutofillClient() = 0;
+#if defined(TIZEN_AUTOFILL_FW)
+  virtual void ResetLastInteractedElements() = 0;
+#endif
 
   virtual void SetContentCaptureClient(WebContentCaptureClient*) = 0;
   virtual WebContentCaptureClient* ContentCaptureClient() const = 0;
index 4289ba9..0d06c05 100644 (file)
@@ -262,4 +262,9 @@ Image* WebElement::GetImage() {
   return Unwrap<Element>()->ImageContents();
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void WebElement::Focus() {
+  Unwrap<Element>()->Focus();
+}
+#endif
 }  // namespace blink
index 3ed5097..9be4743 100644 (file)
@@ -4252,6 +4252,16 @@ gfx::Rect WebFrameWidgetImpl::RequestSelectionRect() {
   return gfx::Rect(View()->CurrentSelectionRect());
 }
 
+void WebFrameWidgetImpl::ResetLastInteractedElements() {
+#if defined(TIZEN_AUTOFILL_FW)
+  if (!View())
+    return;
+
+  if (auto* frame = View()->FocusedFrame())
+    frame->ResetLastInteractedElements();
+#endif
+}
+
 void WebFrameWidgetImpl::PrintToPdf(uint32_t width,
                                     uint32_t height,
                                     const base::FilePath& filename) {
index 098e503..1ffa652 100644 (file)
@@ -716,6 +716,7 @@ class CORE_EXPORT WebFrameWidgetImpl
   SkColor GetBackgroundColor() override;
   gfx::RectF UpdateFocusedNodeBounds() override;
   void SetLongPollingGlobalTimeout(uint64_t timeout) override;
+  void ResetLastInteractedElements() override;
   void PrintToPdf(uint32_t width,
                   uint32_t height,
                   const base::FilePath& filename) override;
index c041fe2..cb4f991 100644 (file)
@@ -2618,6 +2618,12 @@ WebAutofillClient* WebLocalFrameImpl::AutofillClient() {
   return autofill_client_;
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void WebLocalFrameImpl::ResetLastInteractedElements() {
+  autofill_client_->ForceResetLastInteractedElements();
+}
+#endif
+
 void WebLocalFrameImpl::SetContentCaptureClient(
     WebContentCaptureClient* content_capture_client) {
   content_capture_client_ = content_capture_client;
index b226256..5cf3aa8 100644 (file)
@@ -252,6 +252,9 @@ class CORE_EXPORT WebLocalFrameImpl final
   void ReplaceSelection(const WebString&) override;
   void DeleteSurroundingText(int before, int after) override;
   void DeleteSurroundingTextInCodePoints(int before, int after) override;
+#if defined(TIZEN_AUTOFILL_FW)
+  void ResetLastInteractedElements() override;
+#endif
   void SetTextCheckClient(WebTextCheckClient*) override;
   void SetSpellCheckPanelHostClient(WebSpellCheckPanelHostClient*) override;
   WebSpellCheckPanelHostClient* SpellCheckPanelHostClient() const override {
index dbeadca..386b192 100644 (file)
@@ -510,6 +510,10 @@ void WidgetBase::PrintToPdf(uint32_t width,
   client_->PrintToPdf(width, height, filename);
 }
 
+void WidgetBase::ResetLastInteractedElements() {
+  client_->ResetLastInteractedElements();
+}
+
 void WidgetBase::QueryInputType(QueryInputTypeCallback callback) {
   std::move(callback).Run(client_->QueryInputType());
 }
index e1bda87..b3b9fe2 100644 (file)
@@ -154,6 +154,7 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
   void SelectClosestWord(uint32_t x, uint32_t y) override;
   void SelectFocusedLink() override;
   void RequestSelectionRect(RequestSelectionRectCallback callback) override;
+  void ResetLastInteractedElements() override;
 #endif
 #if defined(TIZEN_VIDEO_HOLE)
   void SetVideoHoleForRender(bool enable) override;
index 136d981..1fb024d 100644 (file)
@@ -185,6 +185,7 @@ class WidgetBaseClient {
   virtual void SelectClosestWord(uint32_t x, uint32_t y) {}
   virtual void SelectFocusedLink() {}
   virtual gfx::Rect RequestSelectionRect() { return gfx::Rect(); }
+  virtual void ResetLastInteractedElements() {}
 #endif
 #if defined(TIZEN_VIDEO_HOLE)
   virtual void SetVideoHoleForRender(bool enable) {}
index c35acbd..d6e0bae 100644 (file)
@@ -318,6 +318,63 @@ config("capi-system-sensor-public") {
   }
 }
 
+config("capi-ui-autofill") {
+  if (tizen_autofill_fw) {
+    ldflags = [ "-capi-ui-autofill" ]
+  }
+}
+
+tizen_pkg_config("libcapi-ui-autofill") {
+  packages = []
+  if (tizen_autofill_fw) {
+    packages = [ "capi-ui-autofill" ]
+  }
+}
+
+config("capi-ui-autofill-public") {
+  if (tizen_autofill_fw) {
+    cflags = [ "-capi-ui-autofill" ]
+  }
+}
+
+config("capi-ui-autofill-common") {
+  if (tizen_autofill_fw) {
+    ldflags = [ "-capi-ui-autofill-common" ]
+  }
+}
+
+tizen_pkg_config("libcapi-ui-autofill-common") {
+  packages = []
+  if (tizen_autofill_fw) {
+    packages = [ "capi-ui-autofill-common" ]
+  }
+}
+
+config("capi-ui-autofill-common-public") {
+  if (tizen_autofill_fw) {
+    cflags = [ "-capi-ui-autofill-common" ]
+  }
+}
+
+config("capi-ui-autofill-service") {
+  if (tizen_autofill_fw) {
+    ldflags = [ "-capi-ui-autofill-service" ]
+  }
+}
+
+tizen_pkg_config("libcapi-ui-autofill-service") {
+  packages = []
+  if (tizen_autofill_fw) {
+    packages = [ "capi-ui-autofill-service" ]
+  }
+}
+
+config("capi-ui-autofill-service-public") {
+  if (tizen_autofill_fw) {
+    cflags = [ "-capi-ui-autofill-service" ]
+  }
+}
+
 config("capi-system-system-settings") {
   if (is_tizen) {
     ldflags = [ "-lcapi-system-system-settings" ]
index 92af58d..f86bfd2 100644 (file)
@@ -62,8 +62,11 @@ config("tizen_feature_flags") {
     if (tizen_audio_io) {
       defines += [ "TIZEN_MULTIMEDIA_USE_CAPI_AUDIO_IO" ]
     }
-    if (tizen_autofill_support) {
-      defines += [ "TIZEN_AUTOFILL_SUPPORT" ]
+    if (tizen_autofill) {
+      defines += [ "TIZEN_AUTOFILL" ]
+      if (tizen_autofill_fw) {
+        defines += [ "TIZEN_AUTOFILL_FW" ]
+      }
     }
     if (use_ttrace) {
       defines += [ "USE_TTRACE" ]
index 88e4c5c..2cf0fc4 100644 (file)
@@ -61,13 +61,15 @@ declare_args() {
   tizen_audio_io = false
   tizen_web_speech_recognition = false
 
-  tizen_autofill_support = false
+  tizen_autofill = false
+  tizen_autofill_fw = false
 }
 
-if (tizen_product_tv) {
-  tizen_autofill_support = false
-} else {
-  tizen_autofill_support = true
+if (is_tizen) {
+  tizen_autofill = true
+  if (tizen_product_tv) {
+    tizen_autofill_fw = true
+  }
 }
 
 if (use_ttrace) {
index 54a8a64..eacbd7d 100755 (executable)
@@ -196,8 +196,6 @@ shared_library("chromium-ewk") {
   sources = [
     "authentication_challenge_popup.cc",
     "authentication_challenge_popup.h",
-    "browser/autofill_popup_view_efl.cc",
-    "browser/autofill_popup_view_efl.h",
     "browser/background_sync_controller_efl.cc",
     "browser/background_sync_controller_efl.h",
     "browser/browsing_data_remover_efl.cc",
@@ -306,10 +304,6 @@ shared_library("chromium-ewk") {
     # Make use of Android webview"s simplified pref class.
     "browser/autofill/autocomplete_history_manager_factory.cc",
     "browser/autofill/autocomplete_history_manager_factory.h",
-    "browser/autofill/autofill_client_efl.cc",
-    "browser/autofill/autofill_client_efl.h",
-    "browser/autofill/personal_data_manager_factory.cc",
-    "browser/autofill/personal_data_manager_factory.h",
     "browser/favicon/favicon_commands.cc",
     "browser/favicon/favicon_commands.h",
     "browser/favicon/favicon_database.cc",
@@ -623,6 +617,28 @@ shared_library("chromium-ewk") {
     ]
   }
 
+  if (tizen_autofill) {
+    sources += [
+      "browser/autofill/autofill_client_efl.cc",
+      "browser/autofill/autofill_client_efl.h",
+      "browser/autofill/personal_data_manager_factory.cc",
+      "browser/autofill/personal_data_manager_factory.h",
+      "browser/autofill_popup_view_efl.cc",
+      "browser/autofill_popup_view_efl.h",
+    ]
+
+    if (tizen_autofill_fw) {
+      sources += [
+        "browser/autofill/autofill_login_request.cc",
+        "browser/autofill/autofill_login_request.h",
+        "browser/autofill/autofill_request.cc",
+        "browser/autofill/autofill_request.h",
+        "browser/autofill/autofill_request_manager.cc",
+        "browser/autofill/autofill_request_manager.h",
+      ]
+    }
+  }
+
   if (tizen_product_tv) {
     sources += [
       "common/application_type.cc",
index 692b5d1..7c55513 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/autofill/autocomplete_history_manager_factory.h"
 
@@ -63,4 +63,4 @@ AutocompleteHistoryManagerFactoryEfl::~AutocompleteHistoryManagerFactoryEfl() {
 
 }  // namespace autofill
 
-#endif  // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index e9c381b..7089c83 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_
 #define AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 #include "base/compiler_specific.h"
 #include "base/containers/id_map.h"
 #include "base/memory/ref_counted.h"
@@ -49,5 +49,5 @@ class AutocompleteHistoryManagerFactoryEfl {
 };
 
 }  // namespace autofill
-#endif  // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 #endif  // AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_
index 8b671fe..8268f6a 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/autofill/autofill_client_efl.h"
 
@@ -113,6 +113,13 @@ void AutofillClientEfl::ShowAutofillPopup(
     const PopupOpenArgs& open_args,
     base::WeakPtr<autofill::AutofillPopupDelegate> delegate) {
   DCHECK(web_contents_);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " suggestions.size : " << open_args.suggestions.size();
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " Autofill fw is enabled. return directly";
+  return;
+#endif
   // Do not show sugestions when Remember form data is disabled
   if (!IsAutocompleteSavingEnabled())
     return;
@@ -207,6 +214,11 @@ void AutofillClientEfl::ExecuteCommand(int id) {
 }
 
 void AutofillClientEfl::HideAutofillPopup(PopupHidingReason reason) {
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " Autofill fw is enabled. return directly";
+  return;
+#endif
   if (popup_controller_) {
     popup_controller_->Hide();
   }
@@ -278,6 +290,11 @@ payments::PaymentsClient* AutofillClientEfl::GetPaymentsClient() {
 
 void AutofillClientEfl::ShowSavePasswordPopup(
     std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save) {
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << " Autofill fw is enabled. return directly";
+  return;
+#endif
   if (GetOrCreatePopupController())
     popup_controller_->ShowSavePasswordPopup(std::move(form_to_save));
 }
@@ -320,6 +337,15 @@ void AutofillClientEfl::UpdateAutofillIfRequired() {
   }
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void AutofillClientEfl::ResetLastInteractedElements() {
+  auto* rwhva = static_cast<content::RenderWidgetHostViewAura*>(
+      web_contents_->GetRenderWidgetHostView());
+  if (rwhva)
+    rwhva->host()->ResetLastInteractedElements();
+}
+#endif
+
 void AutofillClientEfl::DidChangeFocusedNodeBounds(
     const gfx::RectF& node_bounds) {
   if (popup_controller_)
@@ -473,4 +499,4 @@ void AutofillClientEfl::HideTouchToFillCreditCard() {
 WEB_CONTENTS_USER_DATA_KEY_IMPL(AutofillClientEfl);
 }  // namespace autofill
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index b0b3894..e6ea207 100644 (file)
@@ -4,7 +4,7 @@
 #ifndef AUTOFILL_MANAGER_DELEGATE_EFL_H
 #define AUTOFILL_MANAGER_DELEGATE_EFL_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
@@ -156,6 +156,9 @@ class AutofillClientEfl
       std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save);
   void SetEWebView(EWebView* view) { webview_ = view; }
   void UpdateAutofillIfRequired();
+#if defined(TIZEN_AUTOFILL_FW)
+  void ResetLastInteractedElements();
+#endif
   void DidChangeFocusedNodeBounds(const gfx::RectF& node_bounds);
   bool IsAutocompleteSavingEnabled();
   FormDataImporter* GetFormDataImporter();
@@ -189,7 +192,7 @@ class AutofillClientEfl
 
 }  // namespace autofill
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif  // AUTOFILL_CLIENT_EFL_H
 
diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_login_request.cc b/tizen_src/ewk/efl_integration/browser/autofill/autofill_login_request.cc
new file mode 100644 (file)
index 0000000..143bd49
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "browser/autofill/autofill_login_request.h"
+
+namespace autofill {
+
+AutofillLoginRequest::AutofillLoginRequest(std::string& signon_realm,
+                                           GURL& origin,
+                                           std::string& username)
+    : signon_realm_(signon_realm), origin_(origin), username_(username) {}
+
+AutofillLoginRequest::~AutofillLoginRequest() {}
+
+void AutofillLoginRequest::AddGroup() {
+  AutofillGroup group;
+  groups_.push_back(group);
+}
+
+void AutofillLoginRequest::AddItem(std::string& id,
+                                   std::string& value,
+                                   autofill_hint_e hint) {
+  if (groups_.empty()) {
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__ << " group is empty";
+    return;
+  }
+
+  AutofillItem item;
+  item.id_ = id;
+  item.value_ = value;
+  item.hint_ = hint;
+
+  groups_.back().items_.push_back(item);
+}
+
+void AutofillLoginRequest::FillMatchingLogins() {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__;
+  if (groups_.empty()) {
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__ << " group is empty";
+    return;
+  }
+
+  auto group = groups_.back();
+  int count = group.items_.size();
+  password_manager::PasswordForm account;
+
+  account.signon_realm = signon_realm_;
+  account.url = origin_;
+  account.scheme = password_manager::PasswordForm::Scheme::kHtml;
+  account.type = password_manager::PasswordForm::Type::kFormSubmission;
+  account.blocked_by_user = false;
+
+  for (int i = 0; i < count; i++) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__
+              << " id : " << group.items_[i].id_.c_str()
+              << " hint : " << group.items_[i].hint_;
+    switch (group.items_[i].hint_) {
+      case AUTOFILL_HINT_ID:
+        account.username_element = base::UTF8ToUTF16(group.items_[i].id_);
+        account.username_value = base::UTF8ToUTF16(group.items_[i].value_);
+        break;
+      case AUTOFILL_HINT_PASSWORD:
+        account.password_element = base::UTF8ToUTF16(group.items_[i].id_);
+        account.password_value = base::UTF8ToUTF16(group.items_[i].value_);
+        break;
+      default:
+        LOG(INFO) << "[Autofill] " << __FUNCTION__ << " hint error";
+        return;
+    }
+  }
+  fetched_forms_.push_back(std::move(account));
+}
+
+std::vector<std::unique_ptr<password_manager::PasswordForm>>
+AutofillLoginRequest::GetResult() {
+  std::vector<std::unique_ptr<password_manager::PasswordForm>> res;
+  for (const auto& form : fetched_forms_)
+    res.push_back(std::make_unique<password_manager::PasswordForm>(form));
+  return res;
+}
+
+}  // namespace autofill
diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_login_request.h b/tizen_src/ewk/efl_integration/browser/autofill/autofill_login_request.h
new file mode 100644 (file)
index 0000000..9792487
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AUTOFILL_LOGIN_REQUEST_H
+#define AUTOFILL_LOGIN_REQUEST_H
+
+#include <autofill_common.h>
+
+#include "base/memory/ref_counted.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_store.h"
+
+namespace autofill {
+
+class AutofillLoginRequest {
+ public:
+  AutofillLoginRequest(std::string& signon_realm,
+                       GURL& origin,
+                       std::string& username);
+  ~AutofillLoginRequest();
+
+  AutofillLoginRequest(const AutofillLoginRequest&) = delete;
+  AutofillLoginRequest& operator=(const AutofillLoginRequest&) = delete;
+
+  void AddGroup();
+  void AddItem(std::string& id, std::string& value, autofill_hint_e hint);
+  void FillMatchingLogins();
+  const GURL& Origin() { return origin_; }       // LCOV_EXCL_LINE
+  std::string& Username() { return username_; }  // LCOV_EXCL_LINE
+
+  // fetched_forms_ may be reused (eg. google login case).
+  // In order to avoid redundant communication with autofill service,
+  // make copies of already fetched forms
+  std::vector<std::unique_ptr<password_manager::PasswordForm>> GetResult();
+
+ private:
+  struct AutofillItem {
+    std::string id_;
+    std::string value_;
+    autofill_hint_e hint_;
+  };
+
+  struct AutofillGroup {
+    std::vector<AutofillItem> items_;
+  };
+
+  std::string signon_realm_;
+  GURL origin_;
+  std::string username_;
+  std::vector<AutofillGroup> groups_;
+
+  std::vector<password_manager::PasswordForm> fetched_forms_;
+};
+
+}  // namespace autofill
+#endif  // AUTOFILL_LOGIN_REQUEST_H
diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_request.cc b/tizen_src/ewk/efl_integration/browser/autofill/autofill_request.cc
new file mode 100644 (file)
index 0000000..33cb953
--- /dev/null
@@ -0,0 +1,446 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "browser/autofill/autofill_request.h"
+
+namespace {
+
+using autofill::AutofillRequest;
+
+void ConnectionStatusChangedCb(autofill_h autofill,
+                               autofill_connection_status_e status,
+                               void* obj) {
+  AutofillRequest* self = static_cast<AutofillRequest*>(obj);
+  self->ConnectionStatusChanged(status);
+}
+
+bool AutofillDataItemCb(autofill_fill_response_item_h item, void* obj) {
+  AutofillRequest* self = static_cast<AutofillRequest*>(obj);
+  return self->AutofillDataItem(item);
+}
+
+bool AutofillDataGroupCb(autofill_fill_response_group_h group_h, void* obj) {
+  AutofillRequest* self = static_cast<AutofillRequest*>(obj);
+  return self->AutofillDataGroup(group_h);
+}
+
+void AutofillDataCb(autofill_h ah,
+                    autofill_fill_response_h fill_response,
+                    void* obj) {
+  AutofillRequest* self = static_cast<AutofillRequest*>(obj);
+  self->AutofillData(fill_response);
+}
+
+void AuthInfoCb(autofill_h ah, autofill_auth_info_h auth_info_h, void* obj) {
+  AutofillRequest* self = static_cast<AutofillRequest*>(obj);
+  self->AuthInfo(auth_info_h);
+}
+
+// called when user clicks 'cancel' or timout scenario
+void AutofillErrorInfoCb(autofill_h ah,
+                         autofill_error_info_h error_info,
+                         void* obj) {
+  AutofillRequest* self = static_cast<AutofillRequest*>(obj);
+  self->AutofillErrorInfo(error_info);
+}
+
+// Autofill team requires that all data stored in DB should be in https.
+// So need to replace http to https.
+void ConvertToHttps(std::string& origin) {
+  std::string from(url::kHttpScheme);
+  std::string to(url::kHttpsScheme);
+  size_t start_pos = 0;
+  while ((start_pos = origin.find(from, start_pos)) != std::string::npos) {
+    origin.replace(start_pos, from.length(), to);
+    start_pos += to.length();
+  }
+  LOG(INFO) << "[Autofill] replace http to https: " << origin;
+}
+
+}  // namespace
+
+namespace autofill {
+
+void AutofillRequest::ConnectionStatusChanged(
+    autofill_connection_status_e status) {
+  char* result;
+  if (AUTOFILL_CONNECTION_STATUS_CONNECTED == status) {
+    ChangeStateTo(State::kReady);
+    result = " connected";
+  } else {
+    ChangeStateTo(State::kMute);
+    if (AUTOFILL_CONNECTION_STATUS_DISCONNECTED == status)
+      result = " disconnected";
+    else if (AUTOFILL_CONNECTION_STATUS_REJECTED == status)
+      result = " rejected";
+    else
+      result = " unknown";
+  }
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << result;
+}
+
+void AutofillRequest::PrepareAutofillObjects() {
+  /* LCOV_EXCL_START */
+  if (view_info_) {
+    autofill_view_info_destroy(view_info_);
+    view_info_ = nullptr;
+  }
+
+  if (!item_) {
+    autofill_item_create(&item_);
+    autofill_item_set_autofill_hint(item_, AUTOFILL_HINT_ID);
+  }
+
+  if (!password_) {
+    autofill_item_create(&password_);
+    autofill_item_set_autofill_hint(password_, AUTOFILL_HINT_PASSWORD);
+  }
+  /* LCOV_EXCL_STOP */
+}
+
+bool AutofillRequest::AutofillDataItem(autofill_fill_response_item_h item) {
+  char* id = nullptr;
+  char* value = nullptr;
+  autofill_hint_e hint;
+  autofill_fill_response_item_get_id(item, &id);
+  autofill_fill_response_item_get_value(item, &value);
+  autofill_fill_response_item_get_autofill_hint(item, &hint);
+
+  std::string str_id(id);
+  std::string str_value(value);
+  if (!(str_id.empty()) && !(str_value.empty())) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << " AddItem: " << str_id.c_str()
+              << " hint: " << hint;
+    login_request_->AddItem(str_id, str_value, hint);
+  }
+
+  if (id)
+    free(id);
+  if (value)
+    free(value);
+  return true;
+}
+
+bool AutofillRequest::AutofillDataGroup(
+    autofill_fill_response_group_h group_h) {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__;
+  login_request_->AddGroup();
+  autofill_fill_response_group_foreach_item(group_h, AutofillDataItemCb, this);
+  return true;
+}
+
+void AutofillRequest::AutofillData(autofill_fill_response_h fill_response) {
+  autofill_fill_response_foreach_group(fill_response, AutofillDataGroupCb,
+                                       this);
+
+  // TODO(djmix.kim) : Only one autofill data will be sent by autofill app.
+  login_request_->FillMatchingLogins();
+
+  ChangeStateTo(State::kFetched);
+  fetch_event_->Signal();
+}
+
+void AutofillRequest::RequestAutofillData() {
+  autofill_fill_response_set_received_cb(autofill_, AutofillDataCb, this);
+  autofill_error_info_set_received_cb(autofill_, AutofillErrorInfoCb, this);
+  // After authen popup, AutofillDataCb is called.
+  // Which means, popup is triggered in autofill_fill_request, but before
+  // calling AutofillDataCb
+  int ret = autofill_fill_request(autofill_, view_info_);
+
+  if (ret == AUTOFILL_ERROR_NONE) {
+    LOG(INFO) << "[Autofill] fill_request returned no error";
+  } else {
+    LOG(ERROR) << "[Autofill] fill_request returned error: " << ret;
+    ChangeStateTo(State::kReady);
+    fetch_event_->Signal();
+  }
+}
+
+void AutofillRequest::AuthInfo(autofill_auth_info_h auth_info_h) {
+  char* view_id = nullptr;
+  autofill_auth_info_get_view_id(auth_info_h, &view_id);
+  std::string origin = login_request_->Origin().spec();
+  if (login_request_->Origin().SchemeIs(url::kHttpScheme))
+    ConvertToHttps(origin);
+
+  if ((!view_id) || origin.compare(view_id)) {
+    LOG(ERROR) << "[Autofill] view_id not match! value in auth_info: "
+               << view_id << ", value in login_request_: " << origin
+               << ", fetching procedure terminates here";
+    ChangeStateTo(State::kReady);
+    fetch_event_->Signal();
+    if (view_id)
+      free(view_id);
+    return;
+  }
+
+  bool autofill_data_present = false;
+  autofill_auth_info_get_autofill_data_present(auth_info_h,
+                                               &autofill_data_present);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << ", auth origin: " << view_id
+            << ", exist autofill data: " << autofill_data_present;
+  free(view_id);
+
+  if (autofill_data_present) {
+    RequestAutofillData();
+  } else {
+    ChangeStateTo(State::kFetched);  // empty result
+    fetch_event_->Signal();
+  }
+}
+
+void AutofillRequest::AutofillErrorInfo(autofill_error_info_h error_info) {
+  LOG(INFO) << "[Autofill] ErrorInfo callback triggered at state "
+            << ShowState(state_);
+  if (State::kFetching == state_) {
+    ChangeStateTo(State::kReady);
+    fetch_event_->Signal();
+  }
+}
+
+void AutofillRequest::CheckAutofillData(base::WaitableEvent* fetch_event,
+                                        std::string& signon_realm,
+                                        GURL& origin,
+                                        std::string& username) {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << ", signon_realm: " << signon_realm
+            << ", origin: " << origin.spec() << ", username: " << username
+            << ", now state: " << ShowState(state_);
+  switch (state_) {
+    case State::kReady:
+    case State::kCommitted:
+      break;
+    case State::kFetched:
+      // TODO?: This is workaround. AutofillRequest should handle multiple
+      // login requests.
+      if (login_request_->Origin() == origin) {
+        LOG(INFO) << "[Autofill]" << __FUNCTION__
+                  << " reuse last time fetched result for same host: "
+                  << origin.spec();
+        fetch_event->Signal();
+        return;
+      }
+      break;
+    default:
+      fetch_event->Signal();
+      return;
+  }
+  std::string view_id = origin.spec();
+  if (origin.SchemeIs(url::kHttpScheme))
+    ConvertToHttps(view_id);
+
+  ChangeStateTo(State::kFetching);
+  PrepareAutofillObjects();
+  login_request_.reset(
+      new AutofillLoginRequest(signon_realm, origin, username));
+  fetch_event_ = fetch_event;
+
+  char* app_id = nullptr;
+  app_get_id(&app_id);
+  autofill_item_set_value(item_, username.c_str());
+  autofill_view_info_create(&view_info_);
+  autofill_view_info_set_app_id(view_info_, app_id);
+  autofill_view_info_set_view_id(view_info_, view_id.c_str());
+  autofill_view_info_add_item(view_info_, item_);
+  autofill_view_info_add_item(view_info_, password_);
+  if (app_id)
+    free(app_id);
+
+  autofill_auth_info_set_received_cb(autofill_, AuthInfoCb, this);
+  int ret = autofill_auth_info_request(autofill_, view_info_);
+  if (AUTOFILL_ERROR_NONE != ret) {
+    LOG(ERROR) << "[Autofill] failed to request auth info. error: " << ret;
+    ChangeStateTo(State::kReady);
+    fetch_event_->Signal();
+  }
+}
+
+void AutofillRequest::CommitAutofill(std::string user_element,
+                                     std::string user_value,
+                                     std::string pass_element,
+                                     std::string pass_value,
+                                     GURL& origin,
+                                     std::string title) {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << ", now state: " << ShowState(state_);
+  switch (state_) {
+    case State::kFetched:
+    case State::kReady:
+    case State::kCommitted:
+      break;
+    default:
+      return;
+  }
+  ChangeStateTo(State::kCommitting);
+  std::string view_id = origin.spec();
+  if (origin.SchemeIs(url::kHttpScheme))
+    ConvertToHttps(view_id);
+
+  autofill_save_item_h save_item_id = nullptr;
+  autofill_save_item_h save_item_password = nullptr;
+
+  autofill_save_item_create(&save_item_id);
+  autofill_save_item_set_autofill_hint(save_item_id, AUTOFILL_HINT_ID);
+  autofill_save_item_set_id(save_item_id, user_element.c_str());
+  autofill_save_item_set_label(save_item_id, user_element.c_str());
+  autofill_save_item_set_value(save_item_id, user_value.c_str());
+
+  autofill_save_item_create(&save_item_password);
+  autofill_save_item_set_autofill_hint(save_item_password,
+                                       AUTOFILL_HINT_PASSWORD);
+  autofill_save_item_set_id(save_item_password, pass_element.c_str());
+  autofill_save_item_set_label(save_item_password, pass_element.c_str());
+  autofill_save_item_set_value(save_item_password, pass_value.c_str());
+
+  autofill_save_view_info_h save_view_info = nullptr;
+  char* app_id = nullptr;
+  app_get_id(&app_id);
+
+  // create autofill save view info
+  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_set_view_title(save_view_info, title.c_str());
+
+  autofill_save_view_info_add_item(save_view_info, save_item_id);
+  autofill_save_view_info_add_item(save_view_info, save_item_password);
+  if (app_id)
+    free(app_id);
+
+  int ret = autofill_commit(autofill_, save_view_info);
+  if (ret == AUTOFILL_ERROR_NONE) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << " Succeeded to commit";
+    ChangeStateTo(State::kCommitted);
+  } else {
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__
+               << " Failed to commit. error: " << ret;
+    ChangeStateTo(State::kReady);
+  }
+
+  autofill_save_item_destroy(save_item_id);
+  autofill_save_item_destroy(save_item_password);
+  autofill_save_view_info_destroy(save_view_info);
+}
+
+std::vector<std::unique_ptr<password_manager::PasswordForm>>
+AutofillRequest::GetResult() {
+  if (State::kFetched == state_)
+    return login_request_->GetResult();
+  else
+    return std::vector<std::unique_ptr<password_manager::PasswordForm>>();
+}
+
+void AutofillRequest::OnLogin() {
+  if (State::kFetched == state_)
+    ChangeStateTo(State::kReady);
+  else if (login_request_) {
+    LOG(INFO) << "[Autofill] logged in at state " << ShowState(state_) << ", "
+              << login_request_->Origin().spec();
+  } else {
+    LOG(INFO) << "[Autofill] logged in at state " << ShowState(state_)
+              << ", login_request_ null";
+  }
+}
+
+AutofillRequest::AutofillRequest() : state_(State::kBirth) {
+  // Ideally, create autofill objects and connect only when need(on login forms
+  // observed), instead of in constructor
+  // However, due to constraints of autofill FW, connect here
+  Connect();
+}
+
+bool AutofillRequest::ChangeStateTo(State to) {
+  bool normal = false;
+  switch (to) {
+    case State::kReady:
+      normal = State::kMute != state_;
+      break;
+    case State::kFetching:
+      normal = State::kReady == state_ || State::kFetched == state_ ||
+               State::kCommitted == state_;
+      break;
+    case State::kFetched:
+      normal = State::kFetching == state_;
+      break;
+    case State::kCommitting:
+      normal = State::kReady == state_ || State::kFetched == state_;
+      break;
+    case State::kCommitted:
+      normal = State::kCommitting == state_;
+      break;
+    case State::kMute:
+      normal = State::kBirth == state_;
+      break;
+  }
+  if (!normal) {
+    LOG(ERROR) << "[Autofill] unknown state transition from "
+               << ShowState(state_) << " to " << ShowState(to);
+  }
+  state_ = to;
+  return normal;
+}
+
+// static
+const char* AutofillRequest::ShowState(State value) {
+  switch (value) {
+    case State::kReady:
+      return "ready";
+    case State::kFetched:
+      return "fetched";
+    case State::kCommitted:
+      return "committed";
+    case State::kBirth:
+      return "birth";
+    case State::kMute:
+      return "mute";
+    case State::kFetching:
+      return "fetching";
+    case State::kCommitting:
+      return "committing";
+  }
+}
+
+bool AutofillRequest::Connect() {
+  DCHECK(State::kBirth == state_);
+  int ret = autofill_create(&autofill_);
+  if (ret != AUTOFILL_ERROR_NONE) {
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__
+               << " Failed to create autofill. error: " << ret;
+    ChangeStateTo(State::kMute);
+    return false;
+  }
+
+  ret = autofill_connect(autofill_, ConnectionStatusChangedCb, this);
+  if (AUTOFILL_ERROR_NONE == ret) {
+    LOG(INFO) << "[Autofill] " << __FUNCTION__ << " returning no error";
+  } else {
+    ChangeStateTo(State::kMute);
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__ << " returning error: " << ret;
+  }
+  return AUTOFILL_ERROR_NONE == ret;
+}
+
+AutofillRequest::~AutofillRequest() {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__
+            << ", now state: " << ShowState(state_) << ", view_info_ "
+            << view_info_ << ", item_ " << item_ << ", password_ " << password_
+            << ", autofill_ " << autofill_;
+  // should inform autofill FW about the cancellation of request
+  if (State::kFetching == state_) {
+    autofill_cancel_fill_request(autofill_, view_info_);
+    fetch_event_->Signal();
+  }
+  // clear autofill object
+  if (view_info_)
+    autofill_view_info_destroy(view_info_);
+  if (item_)
+    autofill_item_destroy(item_);
+  if (password_)
+    autofill_item_destroy(password_);
+  if (autofill_)
+    autofill_destroy(autofill_);
+}
+
+}  // namespace autofill
diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_request.h b/tizen_src/ewk/efl_integration/browser/autofill/autofill_request.h
new file mode 100644 (file)
index 0000000..fcf6058
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AUTOFILL_REQUEST_H
+#define AUTOFILL_REQUEST_H
+
+#include <appfw/app.h>
+#include <autofill.h>
+#include <autofill_common.h>
+#include <autofill_service.h>
+#include <vector>
+
+#include "autofill_login_request.h"
+#include "base/synchronization/waitable_event.h"
+#include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_store.h"
+
+namespace autofill {
+
+class AutofillRequest {
+ public:
+  AutofillRequest();
+  ~AutofillRequest();
+
+  AutofillRequest(const AutofillRequest&) = delete;
+  AutofillRequest& operator=(const AutofillRequest&) = delete;
+
+  void CheckAutofillData(base::WaitableEvent* done,
+                         std::string& signon_realm,
+                         GURL& origin,
+                         std::string& username);
+  void CommitAutofill(std::string user_element,
+                      std::string user_value,
+                      std::string pass_element,
+                      std::string pass_value,
+                      GURL& origin,
+                      std::string title);
+  std::vector<std::unique_ptr<password_manager::PasswordForm>> GetResult();
+  void OnLogin();
+
+  // In order to be called in anonymous namespace, put below six functions in
+  // public area. It is required by autofill framework to return 'bool' for
+  // AutofillDataItem and AutofillDataGroup
+  void ConnectionStatusChanged(autofill_connection_status_e status);
+  bool AutofillDataItem(autofill_fill_response_item_h item);
+  bool AutofillDataGroup(autofill_fill_response_group_h group_h);
+  void AutofillData(autofill_fill_response_h fill_response);
+  void AuthInfo(autofill_auth_info_h auth_info_h);
+  void AutofillErrorInfo(autofill_error_info_h error_info);
+
+ private:
+  enum class State {
+    // constructed, but some necessary members are not initialized
+    kBirth,
+    // is able to handle request
+    kReady,
+    // failure in 1st Connect
+    kMute,
+    // started fetching forms but not finished
+    kFetching,
+    // finished fetching forms
+    kFetched,
+    // started saving new forms but not finished
+    kCommitting,
+    // finished saving new forms
+    kCommitted
+  };
+  static const char* ShowState(State value);
+  // return true if the trasition from current state to param state is known,
+  // else false
+  bool ChangeStateTo(State to);
+
+  bool Connect();
+  // |item_| and |password_| are reusable among fetch requests
+  // |view_info_| is not
+  void PrepareAutofillObjects();
+  void RequestAutofillData();
+
+  State state_;
+  std::unique_ptr<AutofillLoginRequest> login_request_;
+  // wait for login form result from autofill service
+  base::WaitableEvent* fetch_event_;
+
+  autofill_item_h item_ = nullptr;
+  autofill_item_h password_ = nullptr;
+  autofill_view_info_h view_info_ = nullptr;
+
+  autofill_h autofill_ = nullptr;
+};
+
+}  // namespace autofill
+#endif  // AUTOFILL_REQUEST_H
diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.cc b/tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.cc
new file mode 100644 (file)
index 0000000..81f453f
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "browser/autofill/autofill_request_manager.h"
+
+namespace autofill {
+
+AutofillRequestManager* AutofillRequestManager::GetInstance() {
+  return base::Singleton<AutofillRequestManager>::get();
+}
+
+AutofillRequestManager::AutofillRequestManager() {}
+
+AutofillRequestManager::~AutofillRequestManager() {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__;
+  autofill_request_.clear();
+}
+
+void AutofillRequestManager::CreateAutofillRequest(Evas_Object* view) {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " view : " << view;
+  base::AutoLock locker(request_lock_);
+  autofill_request_[view] = std::make_unique<AutofillRequest>();
+}
+
+AutofillRequest* AutofillRequestManager::FindRequest(Evas_Object* view) {
+  base::AutoLock locker(request_lock_);
+  auto iter = autofill_request_.find(view);
+  if (iter != autofill_request_.end())
+    return iter->second.get();
+
+  LOG(ERROR) << "[Autofill] " << __FUNCTION__ << " No request : " << view;
+  return nullptr;
+}
+
+void AutofillRequestManager::CheckAutofillData(void* view,
+                                               base::WaitableEvent* done,
+                                               std::string signon_realm,
+                                               GURL origin,
+                                               std::string username) {
+  auto webview = static_cast<Evas_Object*>(view);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " view : " << webview;
+
+  auto request = FindRequest(webview);
+  if (request)
+    request->CheckAutofillData(done, signon_realm, origin, username);
+  else
+    done->Signal();
+}
+
+std::vector<std::unique_ptr<password_manager::PasswordForm>>
+AutofillRequestManager::GetResult(void* view) {
+  auto webview = static_cast<Evas_Object*>(view);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " view : " << webview;
+  auto request = FindRequest(webview);
+  return request
+             ? request->GetResult()
+             : std::vector<std::unique_ptr<password_manager::PasswordForm>>();
+}
+
+void AutofillRequestManager::CommitAutofill(void* view,
+                                            std::string user_element,
+                                            std::string user_value,
+                                            std::string pass_element,
+                                            std::string pass_value,
+                                            GURL& origin,
+                                            std::string title) {
+  auto webview = static_cast<Evas_Object*>(view);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " view : " << webview;
+
+  auto request = FindRequest(webview);
+  if (request) {
+    request->CommitAutofill(user_element, user_value, pass_element, pass_value,
+                            origin, title);
+  }
+}
+
+void AutofillRequestManager::RemoveRequest(Evas_Object* view) {
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " view : " << view;
+  base::AutoLock locker(request_lock_);
+  auto iter = autofill_request_.find(view);
+  if (iter == autofill_request_.end()) {
+    LOG(ERROR) << "[Autofill] " << __FUNCTION__ << " No request : " << view;
+    return;
+  }
+
+  autofill_request_.erase(iter);
+}
+
+void AutofillRequestManager::OnLogin(void* view) {
+  auto webview = static_cast<Evas_Object*>(view);
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " view : " << webview;
+
+  auto request = FindRequest(webview);
+  if (request)
+    request->OnLogin();
+}
+
+}  // namespace autofill
diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.h b/tizen_src/ewk/efl_integration/browser/autofill/autofill_request_manager.h
new file mode 100644 (file)
index 0000000..86cc695
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AUTOFILL_REQUEST_MANAGER_H
+#define AUTOFILL_REQUEST_MANAGER_H
+
+#include <Ecore_Evas.h>
+#include <map>
+
+#include "autofill_request.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
+#include "components/password_manager/core/browser/password_form.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
+namespace autofill {
+
+class AutofillRequestManager {
+ public:
+  static AutofillRequestManager* GetInstance();
+  void CreateAutofillRequest(Evas_Object* view);
+  void CheckAutofillData(void* view,
+                         base::WaitableEvent* done,
+                         std::string signon_realm,
+                         GURL origin,
+                         std::string username);
+  std::vector<std::unique_ptr<password_manager::PasswordForm>> GetResult(
+      void* view);
+  void CommitAutofill(void* view,
+                      std::string user_element,
+                      std::string user_value,
+                      std::string pass_element,
+                      std::string pass_value,
+                      GURL& origin,
+                      std::string title);
+  void RemoveRequest(Evas_Object* view);
+  void OnLogin(void* view);
+
+ private:
+  friend struct base::DefaultSingletonTraits<AutofillRequestManager>;
+
+  AutofillRequestManager();
+  ~AutofillRequestManager();
+
+  AutofillRequestManager(const AutofillRequestManager&) = delete;
+  AutofillRequestManager& operator=(const AutofillRequestManager&) = delete;
+
+  AutofillRequest* FindRequest(Evas_Object* view);
+
+  base::Lock request_lock_;
+  std::map<Evas_Object*, std::unique_ptr<AutofillRequest>> autofill_request_;
+};
+
+}  // namespace autofill
+#endif  // AUTOFILL_REQUEST_MANAGER_H
index 934d66e..abd565e 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/autofill/personal_data_manager_factory.h"
 
@@ -88,4 +88,4 @@ void PersonalDataManagerFactoryEfl::OnPersonalDataChanged() {
 
 }  // namespace autofill
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 6deed3d..5988297 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef PERSONAL_DATA_MANAGER_FACTORY_H
 #define PERSONAL_DATA_MANAGER_FACTORY_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 #include "base/compiler_specific.h"
 #include "base/containers/id_map.h"
 #include "base/memory/ref_counted.h"
@@ -60,5 +60,5 @@ class PersonalDataManagerFactoryEfl : public PersonalDataManagerObserver {
 };
 
 }  // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 #endif // PERSONAL_DATA_MANAGER_FACTORY_H
index 3a221bf..3892eec 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "autofill_popup_view_efl.h"
 #include "base/files/file_path.h"
@@ -360,4 +360,4 @@ void AutofillPopupViewEfl::savePasswordNotNowCb(void* data,
 
 } // namespace autofill
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 52255e9..d8d47ca 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef AUTOFILL_POPUP_EFL_H
 #define AUTOFILL_POPUP_EFL_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include <Ecore.h>
 #include "ecore_x_wayland_wrapper.h"
@@ -68,6 +68,6 @@ class AutofillPopupViewEfl {
 
 } //namespace autofill
 
-#endif //TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif // autofill_popup_efl_h
index 439022b..55781f0 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "password_helper_efl.h"
 
@@ -103,4 +103,4 @@ void RemoveLogins(const scoped_refptr<PasswordStore>& store) {
 
 }  // namespace password_helper
 
-#endif  // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 1018ec1..6ac8142 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_
 #define EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include <vector>
 
@@ -39,5 +39,5 @@ void RemoveLogins(const scoped_refptr<password_manager::PasswordStore>& store);
 
 }  // namespace password_helper
 
-#endif  // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 #endif  // EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_
index a28d1f9..bea0956 100644 (file)
@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/password_manager/password_manager_client_efl.h"
 
@@ -71,6 +71,23 @@ PasswordManagerClientEfl::PasswordManagerClientEfl(
       ContentPasswordManagerDriverFactory::FromWebContents(web_contents);
 }
 
+void PasswordManagerClientEfl::BindReceiver(
+    mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver>
+        pending_receiver,
+    content::RenderFrameHost* rfh) {
+  auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
+  if (!web_contents)
+    return;
+
+  auto* password_manager_client =
+      PasswordManagerClientEfl::FromWebContents(web_contents);
+  if (!password_manager_client)
+    return;
+
+  password_manager_client->password_manager_driver_bindings_.Bind(
+      rfh, std::move(pending_receiver));
+}
+
 PasswordManagerClientEfl::~PasswordManagerClientEfl() {
 }
 
@@ -365,4 +382,4 @@ void PasswordManagerClientEfl::CheckSafeBrowsingReputation(
 WEB_CONTENTS_USER_DATA_KEY_IMPL(PasswordManagerClientEfl);
 }
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index c60d1c5..9a202a7 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef PASSWORD_MANAGER_CLIENT_EFL_H
 #define PASSWORD_MANAGER_CLIENT_EFL_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "base/compiler_specific.h"
 #include "components/autofill/core/browser/logging/log_manager.h"
 #include "content/public/browser/render_frame_host_receiver_set.h"
 #include "content/public/browser/web_contents_user_data.h"
 
+#if defined(TIZEN_AUTOFILL_FW)
+#include "content/browser/web_contents/web_contents_impl.h"
+#endif
+
 class PasswordManager;
 
 namespace content {
 class WebContents;
+#if defined(TIZEN_AUTOFILL_FW)
+class WebContentsImpl;
+#endif
 }
 
 // PasswordManagerClientEfl implements the PasswordManagerClient interface.
 namespace password_manager {
+
 class PasswordManagerClientEfl
     : public PasswordManagerClient,
       public content::WebContentsUserData<PasswordManagerClientEfl>,
@@ -37,6 +45,10 @@ class PasswordManagerClientEfl
   virtual ~PasswordManagerClientEfl();
   using CredentialsCallback = base::OnceCallback<void(const PasswordForm*)>;
 
+  static void BindReceiver(mojo::PendingAssociatedReceiver<
+                               autofill::mojom::PasswordManagerDriver> receiver,
+                           content::RenderFrameHost* rfh);
+
   static void CreateForWebContentsWithAutofillClient(
       content::WebContents* contents,
       autofill::AutofillClient* autofill_client);
@@ -81,6 +93,15 @@ class PasswordManagerClientEfl
       uint64_t reused_password_hash,
       const std::string& domain) override;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  void* GetWebview() const override {
+    auto wci = static_cast<content::WebContentsImpl*>(web_contents_);
+    if (!wci)
+      return nullptr;
+    return wci->ewk_view();
+  }
+#endif
+
   ukm::SourceId GetUkmSourceId() override;
   PasswordManagerMetricsRecorder* GetMetricsRecorder() override;
   bool IsIsolationForPasswordSitesEnabled() const override;
@@ -182,6 +203,6 @@ class PasswordManagerClientEfl
 };
 }
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif  // PASSWORD_MANAGER_CLIENT_EFL_H
index 4a55a7b..8982456 100644 (file)
@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/password_manager/password_store_factory.h"
 
@@ -77,4 +77,4 @@ void PasswordStoreFactory::Init() {
   service_ = std::make_unique<PasswordStoreService>(ps);
 }
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 58bb14e..e85484c 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef PASSWORD_STORE_FACTORY_H
 #define PASSWORD_STORE_FACTORY_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "base/memory/singleton.h"
 #include "components/password_manager/core/browser/password_manager_driver.h"
@@ -54,6 +54,6 @@ class PasswordStoreFactory {
   std::unique_ptr<PasswordStoreService> service_;
 };
 }
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif  // PASSWORD_STORE_FACTORY_H
index 554dabf..34e7cfc 100644 (file)
@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/webdata/web_data_service.h"
 
@@ -37,4 +37,4 @@ WebDataService::WebDataService()
 WebDataService::~WebDataService() {
 }
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 34ae1a6..20ca098 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef WEB_DATA_SERVICE_H
 #define WEB_DATA_SERVICE_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include <map>
 #include <string>
@@ -61,6 +61,6 @@ class WebDataService : public WebDataServiceBase {
   WebDataService& operator=(const WebDataService&) = delete;
 };
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif  // WEB_DATA_SERVICE_H
index ab37e60..ff20d7d 100644 (file)
@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "browser/webdata/web_data_service_factory.h"
 
@@ -105,4 +105,4 @@ WebDataServiceFactoryEfl* WebDataServiceFactoryEfl::GetInstance() {
   return base::Singleton<WebDataServiceFactoryEfl>::get();
 }
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 9ee9c67..694a243 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef WEB_DATA_SERVICE_FACTORY_H
 #define WEB_DATA_SERVICE_FACTORY_H
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
@@ -58,7 +58,7 @@ class WebDataServiceFactoryEfl {
   WebDataServiceFactoryEfl& operator=(const WebDataServiceFactoryEfl&) = delete;
 };
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif  // WEB_DATA_SERVICE_FACTORY_H
 
index 10f6c53..42e40e8 100644 (file)
@@ -77,7 +77,7 @@ BrowserContextEfl::ResourceContextEfl::ResourceContextEfl(
 
 BrowserContextEfl::~BrowserContextEfl() {
   NotifyWillBeDestroyed();
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   autofill::PersonalDataManagerFactoryEfl::GetInstance()
       ->PersonalDataManagerRemove(this);
   autofill::AutocompleteHistoryManagerFactoryEfl::GetInstance()
@@ -156,7 +156,7 @@ BrowserContextEfl::BrowserContextEfl(EWebContext* web_context, bool incognito)
 
   PrefRegistrySimple* pref_registry = new PrefRegistrySimple();
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   // autofill preferences
   pref_registry->RegisterBooleanPref(kAutofillProfileEnabled, true);
   pref_registry->RegisterBooleanPref(kAutofillWalletImportEnabled, true);
@@ -179,7 +179,7 @@ BrowserContextEfl::BrowserContextEfl(EWebContext* web_context, bool incognito)
 
   user_prefs::UserPrefs::Set(this, user_pref_service_.get());
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   autofill::AutocompleteHistoryManagerFactoryEfl::GetInstance()
       ->AutocompleteHistoryManagerAdd(this);
 #endif
index a3c723d..320bbee 100644 (file)
@@ -40,7 +40,7 @@
 #include "web_contents_delegate_efl.h"
 #include "web_contents_view_delegate_ewk.h"
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 #include "components/autofill/core/common/autofill_switches.h"
 #endif
 
@@ -467,7 +467,7 @@ bool ContentBrowserClientEfl::BindAssociatedReceiverFromFrame(
     RenderFrameHost* render_frame_host,
     const std::string& interface_name,
     mojo::ScopedInterfaceEndpointHandle* handle) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           autofill::switches::kDisableAutofill)) {
     return false;
@@ -480,14 +480,6 @@ bool ContentBrowserClientEfl::BindAssociatedReceiverFromFrame(
         render_frame_host);
     return true;
   }
-  if (interface_name == autofill::mojom::PasswordManagerDriver::Name_) {
-    password_manager::ContentPasswordManagerDriverFactory::
-        BindPasswordManagerDriver(
-            mojo::PendingAssociatedReceiver<
-                autofill::mojom::PasswordManagerDriver>(std::move(*handle)),
-            render_frame_host);
-    return true;
-  }
 #endif
   return false;
 }
index 5940a6f..0296654 100644 (file)
@@ -815,7 +815,7 @@ Evas_Object* EWebContext::AddFaviconObject(const char* uri,
 }
 
 void EWebContext::ClearCandidateData() {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
     content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
         base::BindOnce(&EWebContext::ClearCandidateData,
@@ -835,39 +835,39 @@ void EWebContext::ClearCandidateData() {
     DLOG(WARNING) << "AutofillWebDataService is NULL";
   }
 #else
-  DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled";
+  DLOG(WARNING) << "TIZEN_AUTOFILL is not enabled";
 #endif
 }
 
 void EWebContext::ClearPasswordData() {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   password_helper::RemoveLogins(
       password_manager::PasswordStoreFactory::GetProfilePasswordStore());
 #else
-  DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled";
+  DLOG(WARNING) << "TIZEN_AUTOFILL is not enabled";
 #endif
 }
 
 void EWebContext::ClearPasswordDataForUrl(const char* url) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   password_helper::RemoveLogin(
       password_manager::PasswordStoreFactory::GetProfilePasswordStore(),
       GURL(url));
 #else
-  DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled";
+  DLOG(WARNING) << "TIZEN_AUTOFILL is not enabled";
 #endif
 }
 
 void EWebContext::GetPasswordDataList(
     Ewk_Context_Form_Password_Data_List_Get_Callback callback,
     void* user_data) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   password_helper::GetLogins(
       password_manager::PasswordStoreFactory::GetProfilePasswordStore(),
       base::BindRepeating(&OnGetPasswordDataList, base::Unretained(callback),
                           base::Unretained(user_data)));
 #else
-  DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled";
+  DLOG(WARNING) << "TIZEN_AUTOFILL is not enabled";
 #endif
 }
 
index 13839fe..42aa735 100644 (file)
 #include "eweb_accessibility_util.h"
 #endif
 
+#if defined(TIZEN_AUTOFILL_FW)
+#include "browser/autofill/autofill_request_manager.h"
+#include "components/autofill/core/common/autofill_switches.h"
+#endif
+
 using namespace content;
 using web_contents_utils::WebViewFromWebContents;
 
@@ -448,6 +453,14 @@ EWebView::~EWebView() {
   eweb_accessibility_.reset();
 #endif
 
+#if defined(TIZEN_AUTOFILL_FW)
+  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+          autofill::switches::kDisableAutofill)) {
+    autofill::AutofillRequestManager::GetInstance()->RemoveRequest(
+        evas_object());
+  }
+#endif
+
   select_picker_.reset();
   context_menu_.reset();
   mhtml_callback_map_.Clear();
@@ -642,6 +655,11 @@ Eina_Bool EWebView::GoBack() {
   if (!web_contents_->GetController().CanGoBack())
     return EINA_FALSE;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  if (web_contents_delegate_)
+    web_contents_delegate_->ResetLastInteractedElements();
+#endif
+
   web_contents_->GetController().GoBack();
   return EINA_TRUE;
 }
index b8e1b1d..3d586e2 100644 (file)
 #include "private/ewk_policy_decision_private.h"
 #include "private/ewk_user_media_private.h"
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "private/ewk_autofill_profile_private.h"
+#endif
+
 typedef struct EwkObject Ewk_Auth_Request;
 typedef struct EwkObject Ewk_Download_Job;
 typedef struct EwkObject Ewk_File_Chooser_Request;
@@ -147,6 +151,8 @@ enum CallbackType {
 #if BUILDFLAG(IS_TIZEN_TV)
   HoverOverLink,
   HoverOutLink,
+  LoginFormSubmitted,
+  LoginFields,
 #endif
   URIChanged,
   DidNotAllowScript,
@@ -314,7 +320,14 @@ DECLARE_EWK_VIEW_CALLBACK(NewWindowNavigationPolicyDecision, "policy,decision,ne
 #if BUILDFLAG(IS_TIZEN_TV)
 DECLARE_EWK_VIEW_CALLBACK(HoverOverLink, "hover,over,link", const char*);
 DECLARE_EWK_VIEW_CALLBACK(HoverOutLink, "hover,out,link", const char*);
+DECLARE_EWK_VIEW_CALLBACK(LoginFormSubmitted,
+                          "login,form,submitted",
+                          _Ewk_Form_Info*);
+DECLARE_EWK_VIEW_CALLBACK(LoginFields,
+                          "login,field,identified",
+                          _Ewk_Form_Info*);
 #endif
+
 DECLARE_EWK_VIEW_CALLBACK(ContentsSizeChanged, "contents,size,changed", void);
 DECLARE_EWK_VIEW_CALLBACK(MenuBarVisible, "menubar,visible", bool*);
 DECLARE_EWK_VIEW_CALLBACK(StatusBarVisible, "statusbar,visible", bool*);
index a55861b..abd6ab1 100644 (file)
@@ -49,3 +49,33 @@ void _Ewk_Autofill_Profile::setData(DataType name,
   }
   m_data[name] = value;
 }
+
+#if BUILDFLAG(IS_TIZEN_TV)
+Ewk_Form_Type _Ewk_Form_Info::GetFormType() const {
+  return EWK_FORM_NONE;
+}
+
+const char* _Ewk_Form_Info::GetFormId() const {
+  return "";
+}
+
+const char* _Ewk_Form_Info::GetFormPassword() const {
+  return "";
+}
+
+const char* _Ewk_Form_Info::GetFormUsernameElement() const {
+  return "";
+}
+
+const char* _Ewk_Form_Info::GetFormPasswordElement() const {
+  return "";
+}
+
+const char* _Ewk_Form_Info::GetFormActionUrl() const {
+  return "";
+}
+
+const char* _Ewk_Form_Info::GetFormDomain() const {
+  return "";
+}
+#endif
index 8f8ae8d..5eed1d0 100644 (file)
@@ -9,6 +9,9 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "public/ewk_autofill_profile_product.h"
+#endif
 
 enum DataType {
   PROFILE_ID = 0,
@@ -25,6 +28,32 @@ enum DataType {
   MAX_AUTOFILL
 };
 
+#if BUILDFLAG(IS_TIZEN_TV)
+struct _Ewk_Form_Info {
+  _Ewk_Form_Info(Ewk_Form_Type form_type,
+                 std::string name,
+                 std::string password)
+      : type_(form_type), id_(name), password_(password) {}
+  ~_Ewk_Form_Info(){};
+
+  Ewk_Form_Type GetFormType() const;
+  const char* GetFormId() const;
+  const char* GetFormPassword() const;
+  const char* GetFormUsernameElement() const;
+  const char* GetFormPasswordElement() const;
+  const char* GetFormActionUrl() const;
+  const char* GetFormDomain() const;
+
+  Ewk_Form_Type type_;
+  std::string id_;
+  std::string password_;
+  std::string username_element_;
+  std::string password_element_;
+  std::string action_url_;
+  std::string domain_;
+};
+#endif
+
 class _Ewk_Autofill_Profile {
  public:
   _Ewk_Autofill_Profile();
index 7f09a38..b13bddb 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "ewk_context_form_autofill_profile_private.h"
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include <vector>
 #include <string>
@@ -287,4 +287,4 @@ EwkContextFormAutofillProfileManager::priv_form_autofill_profile_changed_callbac
   personalDataManagerFactory->SetCallback(callback, user_data);
 }
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
index 82f8002..fc68484 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef ewk_context_form_autofill_profile_private_h
 #define ewk_context_form_autofill_profile_private_h
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 
 #include <Evas.h>
 #include <tizen.h>
@@ -99,6 +99,6 @@ class EwkContextFormAutofillProfileManager
         void* user_data);
 };
 
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif  // TIZEN_AUTOFILL
 
 #endif // ewk_context_form_autofill_profile_private_h
index 2a223f1..d192f24 100644 (file)
@@ -71,35 +71,35 @@ Ewk_Form_Type ewk_autofill_profile_form_type_get(Ewk_Form_Info* info)
 const char* ewk_autofill_profile_form_user_name_get(Ewk_Form_Info* info)
 {
   LOG_EWK_API_MOCKUP("This API is not supported");
-  return NULL;
+  return nullptr;
 }
 
 const char* ewk_autofill_profile_form_password_get(Ewk_Form_Info* info)
 {
   LOG_EWK_API_MOCKUP("This API is not supported");
-  return NULL;
+  return nullptr;
 }
 
 const char* ewk_autofill_profile_form_username_element_get(Ewk_Form_Info* info)
 {
   LOG_EWK_API_MOCKUP("This API is not supported");
-  return NULL;
+  return nullptr;
 }
 
 const char* ewk_autofill_profile_form_password_element_get(Ewk_Form_Info* info)
 {
   LOG_EWK_API_MOCKUP("This API is not supported");
-  return NULL;
+  return nullptr;
 }
 
 const char* ewk_autofill_profile_form_action_url_get(Ewk_Form_Info* info)
 {
   LOG_EWK_API_MOCKUP("This API is not supported");
-  return NULL;
+  return nullptr;
 }
 
 const char* ewk_autofill_profile_form_domain_get(Ewk_Form_Info* info)
 {
   LOG_EWK_API_MOCKUP("This API is not supported");
-  return NULL;
+  return nullptr;
 }
index 2d20da3..28b632e 100644 (file)
@@ -463,7 +463,7 @@ void ewk_context_form_autofill_profile_changed_callback_set(
     Ewk_Context_Form_Autofill_Profile_Changed_Callback callback,
     void* user_data)
 {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   EwkContextFormAutofillProfileManager::priv_form_autofill_profile_changed_callback_set(
       callback, user_data);
 #endif
@@ -471,7 +471,7 @@ void ewk_context_form_autofill_profile_changed_callback_set(
 
 Eina_List* ewk_context_form_autofill_profile_get_all(Ewk_Context* context)
 {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (NULL == context) {
     return NULL;
   }
@@ -483,7 +483,7 @@ Eina_List* ewk_context_form_autofill_profile_get_all(Ewk_Context* context)
 
 Ewk_Autofill_Profile* ewk_context_form_autofill_profile_get(Ewk_Context* context, unsigned id)
 {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (NULL == context) {
     return NULL;
   }
@@ -495,7 +495,7 @@ Ewk_Autofill_Profile* ewk_context_form_autofill_profile_get(Ewk_Context* context
 
 Eina_Bool ewk_context_form_autofill_profile_set(Ewk_Context* context, unsigned id, Ewk_Autofill_Profile* profile)
 {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (NULL == context || NULL == profile) {
     return EINA_FALSE;
   }
@@ -508,7 +508,7 @@ Eina_Bool ewk_context_form_autofill_profile_set(Ewk_Context* context, unsigned i
 
 Eina_Bool ewk_context_form_autofill_profile_add(Ewk_Context* context, Ewk_Autofill_Profile* profile)
 {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (NULL == context || NULL == profile) {
     return EINA_FALSE;
   }
@@ -521,7 +521,7 @@ Eina_Bool ewk_context_form_autofill_profile_add(Ewk_Context* context, Ewk_Autofi
 
 Eina_Bool ewk_context_form_autofill_profile_remove(Ewk_Context* context, unsigned id)
 {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (NULL == context) {
     return EINA_FALSE;
   }
index c26c385..29f5697 100644 (file)
@@ -661,7 +661,6 @@ Eina_Bool ewk_view_script_execute(Evas_Object* ewkView, const char* script, Ewk_
   return false;
 }
 
-
 Eina_Bool ewk_view_plain_text_get(Evas_Object* view, Ewk_View_Plain_Text_Get_Callback callback, void* user_data)
 {
   EWK_VIEW_IMPL_GET_OR_RETURN(view, impl, EINA_FALSE);
@@ -1702,7 +1701,7 @@ void ewk_view_feed_mouse_wheel(Evas_Object* view,
 
 void ewk_view_auto_login(Evas_Object *view, const char* user_name, const char* password)
 {
-  LOG_EWK_API_MOCKUP();
+  LOG_EWK_API_MOCKUP("This API is not supported.");
 }
 
 void ewk_view_request_manifest(Evas_Object* o,
index fd006f5..56d5447 100644 (file)
@@ -43,7 +43,7 @@
 #include "third_party/blink/public/web/web_view.h"
 #include "url/gurl.h"
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 #include "components/autofill/content/renderer/autofill_agent.h"
 #include "components/autofill/content/renderer/autofill_assistant_agent.h"
 #include "components/autofill/content/renderer/password_autofill_agent.h"
@@ -62,7 +62,7 @@
 #include "common/application_type.h"
 #endif
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 using autofill::AutofillAgent;
 using autofill::AutofillAssistantAgent;
 using autofill::PasswordAutofillAgent;
@@ -128,7 +128,7 @@ void ContentRendererClientEfl::RenderFrameCreated(content::RenderFrame* render_f
   // Deletes itself when render_frame is destroyed.
   new content::GinNativeBridgeDispatcher(render_frame);
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           autofill::switches::kDisableAutofill)) {
     blink::AssociatedInterfaceRegistry* registry =
index f31141f..cd2e77a 100644 (file)
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
 #endif
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL_FW)
+#include "browser/autofill/autofill_request_manager.h"
+#endif
+
+#if defined(TIZEN_AUTOFILL)
 #include "base/command_line.h"
 #include "browser/autofill/autofill_client_efl.h"
 #include "browser/password_manager/password_manager_client_efl.h"
@@ -121,7 +125,7 @@ WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view)
     : web_view_(view),
       web_contents_(view->web_contents()),
       contents_observer_(std::make_unique<WebContentsObserverEfl>(view, this)) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           autofill::switches::kDisableAutofill)) {
     AutofillClientEfl::CreateForWebContents(&web_contents_);
@@ -135,6 +139,11 @@ WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view)
         base::BindRepeating(&autofill::BrowserDriverInitHook, autofill_client,
                             EWebView::GetPlatformLocale()));
   }
+#if defined(TIZEN_AUTOFILL_FW)
+  LOG(INFO) << "[Autofill] " << __FUNCTION__ << " Create AutofillRequest";
+  autofill::AutofillRequestManager::GetInstance()->CreateAutofillRequest(
+      view->evas_object());
+#endif
 #endif
 }
 
@@ -497,7 +506,7 @@ void WebContentsDelegateEfl::SetContentSecurityPolicy(
   contents_observer_->SetContentSecurityPolicy(policy, header_type);
 }
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 void WebContentsDelegateEfl::UpdateAutofillIfRequired() {
   if (AutofillClientEfl* autofill_client =
           AutofillClientEfl::FromWebContents(&web_contents_)) {
@@ -508,7 +517,7 @@ void WebContentsDelegateEfl::UpdateAutofillIfRequired() {
 
 void WebContentsDelegateEfl::OnDidChangeFocusedNodeBounds(
     const gfx::RectF& focused_node_bounds) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (AutofillClientEfl* autofill_client =
           AutofillClientEfl::FromWebContents(&web_contents_)) {
     autofill_client->DidChangeFocusedNodeBounds(focused_node_bounds);
@@ -516,6 +525,15 @@ void WebContentsDelegateEfl::OnDidChangeFocusedNodeBounds(
 #endif
 }
 
+#if defined(TIZEN_AUTOFILL_FW)
+void WebContentsDelegateEfl::ResetLastInteractedElements() {
+  if (AutofillClientEfl* autofill_client =
+          AutofillClientEfl::FromWebContents(&web_contents_)) {
+    autofill_client->ResetLastInteractedElements();
+  }
+}
+#endif
+
 void WebContentsDelegateEfl::FindReply(WebContents* web_contents,
                                        int request_id,
                                        int number_of_matches,
@@ -557,7 +575,7 @@ JavaScriptDialogManager* WebContentsDelegateEfl::GetJavaScriptDialogManager(
 }
 
 void WebContentsDelegateEfl::OnUpdateSettings(const Ewk_Settings* settings) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   PasswordManagerClientEfl* client =
       PasswordManagerClientEfl::FromWebContents(&web_contents_);
   if (client) {
index 8a9a4a7..7245364 100644 (file)
@@ -140,9 +140,14 @@ class WebContentsDelegateEfl : public WebContentsDelegate {
   void UpdateTargetURL(WebContents* source, const GURL& url) override;
 #endif
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   void UpdateAutofillIfRequired();
 #endif
+
+#if defined(TIZEN_AUTOFILL_FW)
+  void ResetLastInteractedElements();
+#endif
+
  private:
   void OnDidGetManifest(Ewk_View_Request_Manifest_Callback callback,
                         void* user_data,
index 05eacbc..415d1c8 100644 (file)
@@ -36,7 +36,7 @@
 #include "private/ewk_context_private.h"
 #endif
 
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
 #include "browser/autofill/autofill_client_efl.h"
 using autofill::AutofillClientEfl;
 #endif
@@ -384,7 +384,7 @@ void WebContentsObserverEfl::OnDidChangeContentsSize(int width, int height) {
 
 void WebContentsObserverEfl::OnDidChangeFocusedNodeBounds(
     const gfx::RectF& focused_node_bounds) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
   if (AutofillClientEfl* autofill_client =
           AutofillClientEfl::FromWebContents(&web_contents_)) {
     autofill_client->DidChangeFocusedNodeBounds(focused_node_bounds);