Commit ca71f697 authored by Scott Wu's avatar Scott Wu Committed by Commit Bot

Extend autofill controller delegate for password autofilling logic in //ios/web_view.

Bug: 865114
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: I48e317b989129cf391ece111df72f98eb62504d1
Reviewed-on: https://chromium-review.googlesource.com/c/1226950
Commit-Queue: Scott Wu <scottwu@chromium.org>
Reviewed-by: default avatarHiroshi Ichikawa <ichikawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596478}
parent f72b3398
......@@ -84,11 +84,9 @@ if (ios_web_view_enable_autofill) {
"public/cwv_autofill_suggestion.h",
"public/cwv_credit_card.h",
"public/cwv_credit_card_verifier.h",
"public/cwv_password_controller.h",
"public/cwv_preferences_autofill.h",
"public/cwv_web_view_autofill.h",
"public/cwv_web_view_configuration_autofill.h",
"public/cwv_web_view_password.h",
]
}
......@@ -235,7 +233,7 @@ if (ios_web_view_enable_autofill) {
"internal/autofill/cwv_credit_card_verifier.mm",
"internal/autofill/cwv_credit_card_verifier_internal.h",
"internal/passwords/cwv_password_controller.mm",
"internal/passwords/cwv_password_controller_internal.h",
"internal/passwords/cwv_password_controller.h",
]
}
......
......@@ -33,6 +33,7 @@
#import "ios/web_view/internal/autofill/cwv_credit_card_verifier_internal.h"
#import "ios/web_view/internal/autofill/web_view_autofill_client_ios.h"
#include "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h"
#import "ios/web_view/internal/passwords/cwv_password_controller.h"
#include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
#include "ios/web_view/internal/web_view_browser_state.h"
......@@ -42,7 +43,8 @@
@interface CWVAutofillController ()<AutofillDriverIOSBridge,
CRWWebStateObserver,
CWVAutofillClientIOSBridge,
FormActivityObserver>
FormActivityObserver,
CWVPasswordControllerDelegate>
@end
......@@ -71,6 +73,9 @@
std::unique_ptr<autofill::FormActivityObserverBridge>
_formActivityObserverBridge;
// Handles password autofilling related logic.
CWVPasswordController* _passwordController;
}
@synthesize delegate = _delegate;
......@@ -116,6 +121,10 @@
_JSAutofillManager = JSAutofillManager;
_JSSuggestionManager = JSSuggestionManager;
_passwordController =
[[CWVPasswordController alloc] initWithWebState:webState
andDelegate:self];
}
return self;
}
......@@ -150,6 +159,7 @@
- (void)fetchSuggestionsForFormWithName:(NSString*)formName
fieldName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
frameID:(NSString*)frameID
completionHandler:
(void (^)(NSArray<CWVAutofillSuggestion*>*))
......@@ -379,14 +389,16 @@ showUnmaskPromptForCard:(const autofill::CreditCard&)creditCard
NSString* nsFieldIdentifier =
base::SysUTF8ToNSString(params.field_identifier);
NSString* nsFrameID = base::SysUTF8ToNSString(GetWebFrameId(frame));
NSString* nsFieldType = base::SysUTF8ToNSString(params.field_type);
NSString* nsValue = base::SysUTF8ToNSString(params.value);
if (params.type == "focus") {
if ([_delegate respondsToSelector:@selector
(autofillController:didFocusOnFieldWithName:fieldIdentifier
:formName:frameID:value:)]) {
:fieldType:formName:frameID:value:)]) {
[_delegate autofillController:self
didFocusOnFieldWithName:nsFieldName
fieldIdentifier:nsFieldIdentifier
fieldType:nsFieldType
formName:nsFormName
frameID:nsFrameID
value:nsValue];
......@@ -394,10 +406,11 @@ showUnmaskPromptForCard:(const autofill::CreditCard&)creditCard
} else if (params.type == "input") {
if ([_delegate respondsToSelector:@selector
(autofillController:didInputInFieldWithName:fieldIdentifier
:formName:frameID:value:)]) {
:fieldType:formName:frameID:value:)]) {
[_delegate autofillController:self
didInputInFieldWithName:nsFieldName
fieldIdentifier:nsFieldIdentifier
fieldType:nsFieldType
formName:nsFormName
frameID:nsFrameID
value:nsValue];
......@@ -405,10 +418,11 @@ showUnmaskPromptForCard:(const autofill::CreditCard&)creditCard
} else if (params.type == "blur") {
if ([_delegate respondsToSelector:@selector
(autofillController:didBlurOnFieldWithName:fieldIdentifier
:formName:frameID:value:)]) {
:fieldType:formName:frameID:value:)]) {
[_delegate autofillController:self
didBlurOnFieldWithName:nsFieldName
fieldIdentifier:nsFieldIdentifier
fieldType:nsFieldType
formName:nsFormName
frameID:nsFrameID
value:nsValue];
......@@ -442,4 +456,34 @@ showUnmaskPromptForCard:(const autofill::CreditCard&)creditCard
_webState = nullptr;
}
#pragma mark - CWVPasswordControllerDelegate
- (void)passwordController:(CWVPasswordController*)passwordController
decidePasswordSavingPolicyForUsername:(NSString*)username
decisionHandler:
(void (^)(CWVPasswordUserDecision decision))
decisionHandler {
if ([self.delegate respondsToSelector:@selector
(autofillController:decidePasswordSavingPolicyForUsername
:decisionHandler:)]) {
[self.delegate autofillController:self
decidePasswordSavingPolicyForUsername:username
decisionHandler:decisionHandler];
}
}
- (void)passwordController:(CWVPasswordController*)passwordController
decidePasswordUpdatingPolicyForUsername:(NSString*)username
decisionHandler:
(void (^)(CWVPasswordUserDecision decision))
decisionHandler {
if ([self.delegate respondsToSelector:@selector
(autofillController:decidePasswordUpdatingPolicyForUsername
:decisionHandler:)]) {
[self.delegate autofillController:self
decidePasswordUpdatingPolicyForUsername:username
decisionHandler:decisionHandler];
}
}
@end
......@@ -116,6 +116,7 @@ TEST_F(CWVAutofillControllerTest, FetchSuggestions) {
[autofill_controller_ fetchSuggestionsForFormWithName:kTestFormName
fieldName:kTestFieldName
fieldIdentifier:kTestFieldIdentifier
fieldType:@""
frameID:kTestFrameId
completionHandler:fetch_completion];
......@@ -217,6 +218,7 @@ TEST_F(CWVAutofillControllerTest, FocusCallback) {
[[delegate expect] autofillController:autofill_controller_
didFocusOnFieldWithName:kTestFieldName
fieldIdentifier:kTestFieldIdentifier
fieldType:@""
formName:kTestFormName
frameID:kTestFrameId
value:kTestFieldValue];
......@@ -247,6 +249,7 @@ TEST_F(CWVAutofillControllerTest, InputCallback) {
[[delegate expect] autofillController:autofill_controller_
didInputInFieldWithName:kTestFieldName
fieldIdentifier:kTestFieldIdentifier
fieldType:@""
formName:kTestFormName
frameID:kTestFrameId
value:kTestFieldValue];
......@@ -276,6 +279,7 @@ TEST_F(CWVAutofillControllerTest, BlurCallback) {
[[delegate expect] autofillController:autofill_controller_
didBlurOnFieldWithName:kTestFieldName
fieldIdentifier:kTestFieldIdentifier
fieldType:@""
formName:kTestFormName
frameID:kTestFrameId
value:kTestFieldValue];
......@@ -307,9 +311,10 @@ TEST_F(CWVAutofillControllerTest, SubmitCallback) {
didSubmitFormWithName:kTestFormName
userInitiated:YES
isMainFrame:YES];
web::FakeWebFrame frame(base::SysNSStringToUTF8(kTestFrameId), true,
GURL::EmptyGURL());
test_form_activity_tab_helper_->DocumentSubmitted(
/*sender_frame*/ nullptr, base::SysNSStringToUTF8(kTestFormName),
/*sender_frame*/ &frame, base::SysNSStringToUTF8(kTestFormName),
/*form_data=*/"",
/*user_initiated=*/true,
/*is_main_frame=*/true);
......@@ -320,7 +325,7 @@ TEST_F(CWVAutofillControllerTest, SubmitCallback) {
isMainFrame:YES];
test_form_activity_tab_helper_->DocumentSubmitted(
/*sender_frame*/ nullptr, base::SysNSStringToUTF8(kTestFormName),
/*sender_frame*/ &frame, base::SysNSStringToUTF8(kTestFormName),
/*form_data=*/"",
/*user_initiated=*/false,
/*is_main_frame=*/true);
......
......@@ -36,7 +36,6 @@
#import "ios/web_view/internal/cwv_script_command_internal.h"
#import "ios/web_view/internal/cwv_scroll_view_internal.h"
#import "ios/web_view/internal/cwv_web_view_configuration_internal.h"
#import "ios/web_view/internal/passwords/cwv_password_controller_internal.h"
#import "ios/web_view/internal/translate/cwv_translation_controller_internal.h"
#import "ios/web_view/internal/translate/web_view_translate_client.h"
#include "ios/web_view/internal/web_view_browser_state.h"
......@@ -104,7 +103,6 @@ NSDictionary* NSDictionaryFromDictionaryValue(
@property(nonatomic, readwrite) NSURL* visibleURL;
#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
@property(nonatomic, readonly) CWVAutofillController* autofillController;
@property(nonatomic, readonly) CWVPasswordController* passwordController;
#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
// Updates the availability of the back/forward navigation properties exposed
......@@ -117,8 +115,6 @@ NSDictionary* NSDictionaryFromDictionaryValue(
#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
// Returns a new CWVAutofillController created from |_webState|.
- (CWVAutofillController*)newAutofillController;
// Returns a new CWVPasswordController created from |_webState|.
- (CWVPasswordController*)newPasswordController;
#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
// Returns a new CWVTranslationController created from |_webState|.
- (CWVTranslationController*)newTranslationController;
......@@ -133,7 +129,6 @@ static NSString* gUserAgentProduct = nil;
#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
@synthesize autofillController = _autofillController;
@synthesize passwordController = _passwordController;
#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
@synthesize canGoBack = _canGoBack;
@synthesize canGoForward = _canGoForward;
......@@ -509,19 +504,6 @@ static NSString* gUserAgentProduct = nil;
JSSuggestionManager:JSSuggestionManager];
}
#pragma mark - Password
- (CWVPasswordController*)passwordController {
if (!_passwordController) {
_passwordController = [self newPasswordController];
}
return _passwordController;
}
- (CWVPasswordController*)newPasswordController {
return [[CWVPasswordController alloc] initWithWebState:_webState.get()];
}
#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
#pragma mark - Preserving and Restoring State
......@@ -609,7 +591,6 @@ static NSString* gUserAgentProduct = nil;
#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL)
// Recreate and restore the delegate only if previously lazily loaded.
// TODO(crbug.com/865114): Add delegate for password controller.
if (_autofillController) {
id<CWVAutofillControllerDelegate> delegate = _autofillController.delegate;
_autofillController = [self newAutofillController];
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_VIEW_INTERNAL_PASSWORDS_CWV_PASSWORD_CONTROLLER_H_
#define IOS_WEB_VIEW_INTERNAL_PASSWORDS_CWV_PASSWORD_CONTROLLER_H_
#import "ios/web/public/web_state/web_state.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, CWVPasswordUserDecision);
@class CWVPasswordController;
// Internal protocol to receive callbacks related to password autofilling.
@protocol CWVPasswordControllerDelegate
// Called when user needs to decide on whether or not to save the
// password for |username|.
// This can happen when user is successfully logging into a web site with a new
// username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
- (void)passwordController:(CWVPasswordController*)passwordController
decidePasswordSavingPolicyForUsername:(NSString*)username
decisionHandler:
(void (^)(CWVPasswordUserDecision decision))
decisionHandler;
// Called when user needs to decide on whether or not to update the
// password for |username|.
// This can happen when user is successfully logging into a web site with a new
// password and an existing username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
- (void)passwordController:(CWVPasswordController*)passwordController
decidePasswordUpdatingPolicyForUsername:(NSString*)username
decisionHandler:
(void (^)(CWVPasswordUserDecision decision))
decisionHandler;
@end
// Implements features that allow saving entered passwords as well as
// autofilling password forms.
@interface CWVPasswordController : NSObject
// Creates a new password controller with the given |webState|.
// |delegate| is used to receive password autofill suggestion callbacks.
- (instancetype)initWithWebState:(web::WebState*)webState
andDelegate:
(nullable id<CWVPasswordControllerDelegate>)delegate
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
#endif // IOS_WEB_VIEW_INTERNAL_PASSWORDS_CWV_PASSWORD_CONTROLLER_H_
......@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/web_view/internal/passwords/cwv_password_controller_internal.h"
#import "ios/web_view/internal/passwords/cwv_password_controller.h"
#include <memory>
#include "base/strings/sys_string_conversions.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/ios/browser/autofill_util.h"
......@@ -18,6 +19,7 @@
#import "ios/web_view/internal/passwords/web_view_password_manager_client.h"
#import "ios/web_view/internal/passwords/web_view_password_manager_driver.h"
#include "ios/web_view/internal/web_view_browser_state.h"
#import "ios/web_view/public/cwv_autofill_controller_delegate.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
......@@ -29,6 +31,7 @@ using autofill::PasswordForm;
using ios_web_view::WebViewPasswordManagerClient;
using ios_web_view::WebViewPasswordManagerDriver;
using password_manager::GetPageURLAndCheckTrustLevel;
using password_manager::PasswordFormManagerForUI;
@interface CWVPasswordController ()<CRWWebStateObserver,
CWVPasswordManagerClientDelegate,
......@@ -42,6 +45,9 @@ using password_manager::GetPageURLAndCheckTrustLevel;
// Helper contains common password controller logic.
@property(nonatomic, readonly) PasswordControllerHelper* helper;
// Delegate to receive password autofill suggestion callbacks.
@property(nonatomic, weak, nullable) id<CWVPasswordControllerDelegate> delegate;
// Informs the |_passwordManager| of the password forms (if any were present)
// that have been found on the page.
- (void)didFinishPasswordFormExtraction:
......@@ -78,6 +84,7 @@ using password_manager::GetPageURLAndCheckTrustLevel;
#pragma mark - Properties
@synthesize helper = _helper;
@synthesize delegate = _delegate;
- (password_manager::PasswordManagerDriver*)passwordManagerDriver {
return _passwordManagerDriver.get();
......@@ -85,7 +92,9 @@ using password_manager::GetPageURLAndCheckTrustLevel;
#pragma mark - Initialization
- (instancetype)initWithWebState:(web::WebState*)webState {
- (instancetype)initWithWebState:(web::WebState*)webState
andDelegate:
(nullable id<CWVPasswordControllerDelegate>)delegate {
self = [super init];
if (self) {
DCHECK(webState);
......@@ -105,6 +114,8 @@ using password_manager::GetPageURLAndCheckTrustLevel;
_credentialsSentToPasswordManager = NO;
_delegate = delegate;
// TODO(crbug.com/865114): Credential manager related logic
}
return self;
......@@ -179,15 +190,64 @@ using password_manager::GetPageURLAndCheckTrustLevel;
}
- (void)showSavePasswordInfoBar:
(std::unique_ptr<password_manager::PasswordFormManagerForUI>)formToSave {
// Always save password for Demo.
// TODO(crbug.com/865114): Implement remaining logic.
formToSave.get()->Save();
(std::unique_ptr<PasswordFormManagerForUI>)formToSave {
if (!self.delegate) {
return;
}
// Use the same logic as iOS Chrome for saving password, see:
// ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.mm
__block std::unique_ptr<PasswordFormManagerForUI> formPtr(
std::move(formToSave));
NSString* userName =
base::SysUTF16ToNSString(formPtr->GetPendingCredentials().username_value);
[self.delegate passwordController:self
decidePasswordSavingPolicyForUsername:userName
decisionHandler:^(
CWVPasswordUserDecision decision) {
switch (decision) {
case CWVPasswordUserDecisionYes:
formPtr->Save();
break;
case CWVPasswordUserDecisionNever:
formPtr->PermanentlyBlacklist();
break;
default:
// Do nothing.
break;
}
}];
}
- (void)showUpdatePasswordInfoBar:
(std::unique_ptr<password_manager::PasswordFormManagerForUI>)formToUpdate {
// TODO(crbug.com/865114): Implement remaining logic.
(std::unique_ptr<PasswordFormManagerForUI>)formToUpdate {
if (!self.delegate) {
return;
}
// Use the same logic as iOS Chrome for updating password, see:
// ios/chrome/browser/passwords/
// ios_chrome_update_password_infobar_delegate.mm
__block std::unique_ptr<PasswordFormManagerForUI> formPtr(
std::move(formToUpdate));
BOOL hasMultipleCredentials =
formPtr->GetBestMatches().size() > 1 && !formPtr->IsPasswordOverridden();
const autofill::PasswordForm& credentials =
hasMultipleCredentials ? *(formPtr->GetPreferredMatch())
: formPtr->GetPendingCredentials();
NSString* userName = base::SysUTF16ToNSString(credentials.username_value);
[self.delegate passwordController:self
decidePasswordUpdatingPolicyForUsername:userName
decisionHandler:^(
CWVPasswordUserDecision decision) {
DCHECK_NE(decision,
CWVPasswordUserDecisionNever);
if (decision == CWVPasswordUserDecisionYes) {
formPtr->Update(credentials);
}
}];
}
- (void)showAutosigninNotification:
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_VIEW_INTERNAL_PASSWORDS_CWV_PASSWORD_CONTROLLER_INTERNAL_H_
#define IOS_WEB_VIEW_INTERNAL_PASSWORDS_CWV_PASSWORD_CONTROLLER_INTERNAL_H_
#import "ios/web/public/web_state/web_state.h"
#import "ios/web_view/public/cwv_password_controller.h"
NS_ASSUME_NONNULL_BEGIN
@interface CWVPasswordController ()
- (instancetype)initWithWebState:(web::WebState*)webState;
@end
NS_ASSUME_NONNULL_END
#endif // IOS_WEB_VIEW_INTERNAL_PASSWORDS_CWV_PASSWORD_CONTROLLER_INTERNAL_H_
......@@ -42,11 +42,13 @@ CWV_EXPORT
// No-op if no such form and field can be found in the current page.
// |fieldIdentifier| identifies the field that had focus. It is passed to
// CWVAutofillControllerDelegate and forwarded to this method.
// |fieldType| is the 'type' attribute of the html field.
// |completionHandler| will only be called on success.
// |frameID| is the ID of the web frame containing the form.
- (void)fetchSuggestionsForFormWithName:(NSString*)formName
fieldName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
frameID:(NSString*)frameID
completionHandler:
(void (^)(NSArray<CWVAutofillSuggestion*>*))
......
......@@ -20,13 +20,25 @@ typedef NS_ENUM(NSInteger, CWVStoragePolicy) {
CWVStoragePolicyAllow, // Allow storage.
};
// User decision for saving / updating password.
// Note: CWVPasswordUserDecisionNever is only used in saving scenarios.
typedef NS_ENUM(NSInteger, CWVPasswordUserDecision) {
CWVPasswordUserDecisionNotThisTime =
0, // Do not save / update password this time.
CWVPasswordUserDecisionNever, // Never save password for this site.
CWVPasswordUserDecisionYes, // Save / update password.
};
// Protocol to receive callbacks related to autofill.
// |fieldName| is the 'name' attribute of a html field.
// |fieldIdentifier| identifies the html field.
// |fieldType| is the 'type' attribute of the html field.
// |formName| is the 'name' attribute of a html <form>.
// |value| is the 'value' attribute of the html field.
// Example:
// <form name='_formName_'>
// <input name='_fieldName_' value='_value_'>
// <input id='_fieldIdentifier_' name='_fieldName_' value='_value_'
// type='_fieldType_'>
// </form>
@protocol CWVAutofillControllerDelegate<NSObject>
......@@ -36,6 +48,7 @@ typedef NS_ENUM(NSInteger, CWVStoragePolicy) {
- (void)autofillController:(CWVAutofillController*)autofillController
didFocusOnFieldWithName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
formName:(NSString*)formName
frameID:(NSString*)frameID
value:(NSString*)value;
......@@ -44,6 +57,7 @@ typedef NS_ENUM(NSInteger, CWVStoragePolicy) {
- (void)autofillController:(CWVAutofillController*)autofillController
didInputInFieldWithName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
formName:(NSString*)formName
frameID:(NSString*)frameID
value:(NSString*)value;
......@@ -52,6 +66,7 @@ typedef NS_ENUM(NSInteger, CWVStoragePolicy) {
- (void)autofillController:(CWVAutofillController*)autofillController
didBlurOnFieldWithName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
formName:(NSString*)formName
frameID:(NSString*)frameID
value:(NSString*)value;
......@@ -77,6 +92,31 @@ typedef NS_ENUM(NSInteger, CWVStoragePolicy) {
- (void)autofillController:(CWVAutofillController*)autofillController
verifyCreditCardWithVerifier:(CWVCreditCardVerifier*)verifier;
// Called when user needs to decide on whether or not to save the
// password for |username|.
// This can happen when user successfully logs into a web site with a new
// username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
// Not implementing it is equivalent of not calling |decisionHandler|.
- (void)autofillController:(CWVAutofillController*)autofillController
decidePasswordSavingPolicyForUsername:(NSString*)username
decisionHandler:
(void (^)(CWVPasswordUserDecision decision))
decisionHandler;
// Called when user needs to decide on whether or not to update the
// password for |username|.
// This can happen when user successfully logs into a web site with a new
// password and an existing username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
// Not implementing it is equivalent of not calling |decisionHandler|.
- (void)autofillController:(CWVAutofillController*)autofillController
decidePasswordUpdatingPolicyForUsername:(NSString*)username
decisionHandler:
(void (^)(CWVPasswordUserDecision decision))
decisionHandler;
@end
NS_ASSUME_NONNULL_END
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_VIEW_PUBLIC_CWV_PASSWORD_CONTROLLER_H_
#define IOS_WEB_VIEW_PUBLIC_CWV_PASSWORD_CONTROLLER_H_
#import <Foundation/Foundation.h>
#import "cwv_export.h"
NS_ASSUME_NONNULL_BEGIN
CWV_EXPORT
// Exposes features that allow saving entered passwords as well as autofilling
// password forms.
@interface CWVPasswordController : NSObject
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
#endif // IOS_WEB_VIEW_PUBLIC_CWV_PASSWORD_CONTROLLER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_VIEW_PUBLIC_CWV_WEB_VIEW_PASSWORD_H_
#define IOS_WEB_VIEW_PUBLIC_CWV_WEB_VIEW_PASSWORD_H_
#import "cwv_web_view.h"
@class CWVPasswordController;
@interface CWVWebView (Password)
// The web view's password controller.
@property(nonatomic, readonly) CWVPasswordController* passwordController;
@end
#endif // IOS_WEB_VIEW_PUBLIC_CWV_WEB_VIEW_PASSWORD_H_
......@@ -43,6 +43,7 @@
- (void)autofillController:(CWVAutofillController*)autofillController
didFocusOnFieldWithName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
formName:(NSString*)formName
frameID:(NSString*)frameID
value:(NSString*)value {
......@@ -81,6 +82,7 @@
[autofillController fetchSuggestionsForFormWithName:formName
fieldName:fieldName
fieldIdentifier:fieldIdentifier
fieldType:fieldType
frameID:frameID
completionHandler:completionHandler];
}
......@@ -88,6 +90,7 @@
- (void)autofillController:(CWVAutofillController*)autofillController
didInputInFieldWithName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
formName:(NSString*)formName
value:(NSString*)value {
// Not implemented.
......@@ -96,6 +99,7 @@
- (void)autofillController:(CWVAutofillController*)autofillController
didBlurOnFieldWithName:(NSString*)fieldName
fieldIdentifier:(NSString*)fieldIdentifier
fieldType:(NSString*)fieldType
formName:(NSString*)formName
value:(NSString*)value {
[_alertController dismissViewControllerAnimated:YES completion:nil];
......@@ -139,6 +143,75 @@
[self presentAlertController:alertController];
}
- (void)autofillController:(CWVAutofillController*)autofillController
decidePasswordSavingPolicyForUsername:(NSString*)userName
decisionHandler:(void (^)(CWVPasswordUserDecision))
decisionHandler {
UIAlertController* alertController =
[self newAlertControllerWithTitle:@"Save Password"
message:
@"Do you want to save your password on "
@"this site?"];
UIAlertAction* noAction = [UIAlertAction
actionWithTitle:@"Not this time"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction* _Nonnull action) {
decisionHandler(CWVPasswordUserDecisionNotThisTime);
}];
[alertController addAction:noAction];
UIAlertAction* neverAction =
[UIAlertAction actionWithTitle:@"Never"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction* _Nonnull action) {
decisionHandler(CWVPasswordUserDecisionNever);
}];
[alertController addAction:neverAction];
UIAlertAction* yesAction =
[UIAlertAction actionWithTitle:@"Save"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction* _Nonnull action) {
decisionHandler(CWVPasswordUserDecisionYes);
}];
[alertController addAction:yesAction];
[self presentAlertController:alertController];
}
- (void)autofillController:(CWVAutofillController*)autofillController
decidePasswordUpdatingPolicyForUsername:(NSString*)userName
decisionHandler:(void (^)(CWVPasswordUserDecision))
decisionHandler {
UIAlertController* alertController = [self
newAlertControllerWithTitle:@"Update Password"
message:
[NSString
stringWithFormat:
@"Do you want to update your password "
@"for %@ on this site?",
userName]];
UIAlertAction* noAction = [UIAlertAction
actionWithTitle:@"Not this time"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction* _Nonnull action) {
decisionHandler(CWVPasswordUserDecisionNotThisTime);
}];
[alertController addAction:noAction];
UIAlertAction* yesAction =
[UIAlertAction actionWithTitle:@"Update"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction* _Nonnull action) {
decisionHandler(CWVPasswordUserDecisionYes);
}];
[alertController addAction:yesAction];
[self presentAlertController:alertController];
}
#pragma mark - Private Methods
- (UIAlertController*)newAlertControllerWithTitle:(NSString*)title
......
......@@ -270,10 +270,6 @@ NSString* const kWebViewShellJavaScriptDialogTextFieldAccessibiltyIdentifier =
_autofillDelegate = [[ShellAutofillDelegate alloc] init];
_webView.autofillController.delegate = _autofillDelegate;
// Triggers password controller initiation.
// TODO(crbug.com/865114): Add delegate for password controller.
[_webView passwordController];
[_webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight];
[_containerView addSubview:_webView];
......
......@@ -30,6 +30,7 @@ NSString* const kTestFormName = @"FormName";
NSString* const kTestFormID = @"FormID";
NSString* const kTestFieldName = @"FieldName";
NSString* const kTestFieldID = @"FieldID";
NSString* const kTestFieldType = @"text";
NSString* const kTestFieldValue = @"FieldValue";
NSString* const kTestSubmitID = @"SubmitID";
NSString* const kTestFormHtml =
......@@ -83,6 +84,7 @@ class WebViewAutofillTest : public WebViewInttestBase {
fetchSuggestionsForFormWithName:kTestFormName
fieldName:kTestFieldName
fieldIdentifier:kTestFieldID
fieldType:kTestFieldType
frameID:GetMainFrameId()
completionHandler:^(
NSArray<CWVAutofillSuggestion*>* suggestions) {
......@@ -122,6 +124,7 @@ TEST_F(WebViewAutofillTest, TestDelegateCallbacks) {
[[delegate expect] autofillController:autofill_controller_
didFocusOnFieldWithName:kTestFieldName
fieldIdentifier:kTestFieldID
fieldType:kTestFieldType
formName:kTestFormName
frameID:[OCMArg any]
value:kTestFieldValue];
......@@ -135,6 +138,7 @@ TEST_F(WebViewAutofillTest, TestDelegateCallbacks) {
[[delegate expect] autofillController:autofill_controller_
didBlurOnFieldWithName:kTestFieldName
fieldIdentifier:kTestFieldID
fieldType:kTestFieldType
formName:kTestFormName
frameID:[OCMArg any]
value:kTestFieldValue];
......@@ -151,6 +155,7 @@ TEST_F(WebViewAutofillTest, TestDelegateCallbacks) {
[[delegate expect] autofillController:autofill_controller_
didInputInFieldWithName:kTestFieldName
fieldIdentifier:kTestFieldID
fieldType:kTestFieldType
formName:kTestFormName
frameID:[OCMArg any]
value:kTestFieldValue];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment