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)
}
}
+#if defined(TIZEN_AUTOFILL_FW)
+void AutofillAgent::ForceResetLastInteractedElements() {
+ form_tracker_.ForceResetLastInteractedElements();
+}
+#endif
+
void AutofillAgent::OnProvisionallySaveForm(
const WebFormElement& form,
const WebFormControlElement& element,
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;
FireProbablyFormSubmitted();
}
+#if defined(TIZEN_AUTOFILL_FW)
+void FormTracker::ForceResetLastInteractedElements() {
+ ResetLastInteractedElements();
+}
+#endif
+
void FormTracker::FormControlDidChangeImpl(
const WebFormControlElement& element,
Observer::ElementChangeSource change_source) {
}
void FireProbablyFormSubmittedForTesting();
+#if defined(TIZEN_AUTOFILL_FW)
+ void ForceResetLastInteractedElements();
+#endif
private:
FRIEND_TEST_ALL_PREFIXES(FormAutocompleteTest,
#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"
using blink::WebString;
using blink::WebVector;
using blink::WebView;
+#if BUILDFLAG(IS_TIZEN_TV)
+using blink::WebString;
+#endif
namespace autofill {
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;
// 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>(
// 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) {
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)) {
(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(
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);
}
}
}
+#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
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_|.
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,
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;
}
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;
}
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 = [
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(
}
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.
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);
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
#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.
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));
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());
// 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();
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;
}
// 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_;
#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 {
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_);
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()));
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.
//
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;
#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,
: 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),
PasswordForm::Scheme scheme;
std::string signon_realm;
GURL url;
+#if defined(TIZEN_AUTOFILL_FW)
+ std::string username;
+#endif
};
// For testing only.
// 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 =
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;
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.
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;
}
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_)) {
}
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;
"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);
// 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.
#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 {
}
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.
// `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());
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;
// 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.
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
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_);
// 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.
#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",
->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(
#define MAYBEVLOG DVLOG
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "tizen_src/ewk/efl_integration/common/content_switches_efl.h"
+#endif
+
namespace content {
namespace {
switches::kDiscardableMemoryLimit,
switches::kDiscardableMemoryPurgeDelay,
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+ switches::kTizenAppId,
+#endif
};
renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
std::size(kSwitchNames));
return;
view_->OnSelectionRectReceived(rect);
}
+
+void RenderWidgetHostImpl::ResetLastInteractedElements() {
+ blink_widget_->ResetLastInteractedElements();
+}
#endif
#if defined(TIZEN_VIDEO_HOLE)
void SelectFocusedLink();
void RequestSelectionRect();
void OnGetSelectionRect(const gfx::Rect& rect);
+ void ResetLastInteractedElements();
#endif
#if defined(TIZEN_VIDEO_HOLE)
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)
SetLongPollingGlobalTimeout(uint64 timeout);
[EnableIf=is_efl]
+ ResetLastInteractedElements();
+
+
+ [EnableIf=is_efl]
PrintToPdf(uint32 width, uint32 height, mojo_base.mojom.FilePath filename);
[EnableIf=tizen_video_hole]
const WebFormControlElement& element,
const WebString& old_value) {}
+#if defined(TIZEN_AUTOFILL_FW)
+ virtual void ForceResetLastInteractedElements() {}
+#endif
+
virtual void DidCompleteFocusChangeInFrame() {}
virtual void DidReceiveLeftMouseDownOrGestureTapInNode(const 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*);
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;
return Unwrap<Element>()->ImageContents();
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void WebElement::Focus() {
+ Unwrap<Element>()->Focus();
+}
+#endif
} // namespace blink
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) {
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;
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;
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 {
client_->PrintToPdf(width, height, filename);
}
+void WidgetBase::ResetLastInteractedElements() {
+ client_->ResetLastInteractedElements();
+}
+
void WidgetBase::QueryInputType(QueryInputTypeCallback callback) {
std::move(callback).Run(client_->QueryInputType());
}
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;
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) {}
}
}
+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" ]
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" ]
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) {
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",
# 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",
]
}
+ 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",
// 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"
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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"
};
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_
// 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"
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;
}
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();
}
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));
}
}
}
+#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_)
WEB_CONTENTS_USER_DATA_KEY_IMPL(AutofillClientEfl);
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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"
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();
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // AUTOFILL_CLIENT_EFL_H
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
// 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"
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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"
};
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // PERSONAL_DATA_MANAGER_FACTORY_H
// 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"
} // namespace autofill
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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"
} //namespace autofill
-#endif //TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // autofill_popup_efl_h
// 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"
} // namespace password_helper
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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>
} // namespace password_helper
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_
// 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"
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() {
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(PasswordManagerClientEfl);
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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>,
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);
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;
};
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // PASSWORD_MANAGER_CLIENT_EFL_H
// 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"
service_ = std::make_unique<PasswordStoreService>(ps);
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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"
std::unique_ptr<PasswordStoreService> service_;
};
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // PASSWORD_STORE_FACTORY_H
// 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"
WebDataService::~WebDataService() {
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#ifndef WEB_DATA_SERVICE_H
#define WEB_DATA_SERVICE_H
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
#include <map>
#include <string>
WebDataService& operator=(const WebDataService&) = delete;
};
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // WEB_DATA_SERVICE_H
// 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"
return base::Singleton<WebDataServiceFactoryEfl>::get();
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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"
WebDataServiceFactoryEfl& operator=(const WebDataServiceFactoryEfl&) = delete;
};
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // WEB_DATA_SERVICE_FACTORY_H
BrowserContextEfl::~BrowserContextEfl() {
NotifyWillBeDestroyed();
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
autofill::PersonalDataManagerFactoryEfl::GetInstance()
->PersonalDataManagerRemove(this);
autofill::AutocompleteHistoryManagerFactoryEfl::GetInstance()
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);
user_prefs::UserPrefs::Set(this, user_pref_service_.get());
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
autofill::AutocompleteHistoryManagerFactoryEfl::GetInstance()
->AutocompleteHistoryManagerAdd(this);
#endif
#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
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;
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;
}
}
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,
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
}
#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;
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();
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;
}
#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;
#if BUILDFLAG(IS_TIZEN_TV)
HoverOverLink,
HoverOutLink,
+ LoginFormSubmitted,
+ LoginFields,
#endif
URIChanged,
DidNotAllowScript,
#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*);
}
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
#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,
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();
#include "ewk_context_form_autofill_profile_private.h"
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
#include <vector>
#include <string>
personalDataManagerFactory->SetCallback(callback, user_data);
}
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#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>
void* user_data);
};
-#endif // TIZEN_AUTOFILL_SUPPORT
+#endif // TIZEN_AUTOFILL
#endif // ewk_context_form_autofill_profile_private_h
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;
}
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
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;
}
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;
}
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;
}
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;
}
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;
}
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);
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,
#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"
#include "common/application_type.h"
#endif
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
using autofill::AutofillAgent;
using autofill::AutofillAssistantAgent;
using autofill::PasswordAutofillAgent;
// 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 =
#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"
: 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_);
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
}
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_)) {
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);
#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,
}
void WebContentsDelegateEfl::OnUpdateSettings(const Ewk_Settings* settings) {
-#if defined(TIZEN_AUTOFILL_SUPPORT)
+#if defined(TIZEN_AUTOFILL)
PasswordManagerClientEfl* client =
PasswordManagerClientEfl::FromWebContents(&web_contents_);
if (client) {
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,
#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
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);