OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/autofill/autofill_controller.h" |
| 6 |
| 7 #include <stdint.h> |
| 8 |
| 9 #include <memory> |
| 10 #include <utility> |
| 11 |
| 12 #include "base/strings/sys_string_conversions.h" |
| 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "components/autofill/core/browser/autofill_manager.h" |
| 15 #include "components/autofill/core/browser/popup_item_ids.h" |
| 16 #include "components/autofill/core/common/autofill_pref_names.h" |
| 17 #import "components/autofill/ios/browser/autofill_client_ios_bridge.h" |
| 18 #include "components/autofill/ios/browser/autofill_driver_ios.h" |
| 19 #include "components/autofill/ios/browser/autofill_driver_ios_bridge.h" |
| 20 #import "components/autofill/ios/browser/form_suggestion.h" |
| 21 #include "components/infobars/core/infobar_manager.h" |
| 22 #include "components/pref_registry/pref_registry_syncable.h" |
| 23 #include "components/prefs/pref_service.h" |
| 24 #include "components/signin/core/browser/profile_identity_provider.h" |
| 25 #include "components/signin/core/browser/signin_manager.h" |
| 26 #include "ios/chrome/browser/application_context.h" |
| 27 #import "ios/chrome/browser/autofill/autofill_agent.h" |
| 28 #import "ios/chrome/browser/autofill/form_suggestion_provider.h" |
| 29 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| 30 #include "ios/chrome/browser/infobars/infobar_manager_impl.h" |
| 31 #include "ios/chrome/browser/pref_names.h" |
| 32 #include "ios/chrome/browser/signin/oauth2_token_service_factory.h" |
| 33 #include "ios/chrome/browser/signin/signin_manager_factory.h" |
| 34 #import "ios/chrome/browser/ui/autofill/autofill_client_ios.h" |
| 35 #import "ios/web/public/web_state/web_state.h" |
| 36 |
| 37 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 38 #error "This file requires ARC support." |
| 39 #endif |
| 40 |
| 41 using autofill::AutofillPopupDelegate; |
| 42 |
| 43 @interface AutofillController ()<AutofillClientIOSBridge, |
| 44 AutofillDriverIOSBridge> { |
| 45 AutofillAgent* _autofillAgent; |
| 46 std::unique_ptr<autofill::AutofillClient> _autofillClient; |
| 47 autofill::AutofillManager* _autofillManager; // weak |
| 48 } |
| 49 |
| 50 @end |
| 51 |
| 52 @implementation AutofillController |
| 53 |
| 54 @synthesize browserState = _browserState; |
| 55 |
| 56 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState |
| 57 webState:(web::WebState*)webState |
| 58 autofillAgent:(AutofillAgent*)autofillAgent |
| 59 passwordGenerationManager: |
| 60 (password_manager::PasswordGenerationManager*) |
| 61 passwordGenerationManager |
| 62 downloadEnabled:(BOOL)downloadEnabled { |
| 63 DCHECK(browserState); |
| 64 DCHECK(webState); |
| 65 self = [super init]; |
| 66 if (self) { |
| 67 _browserState = browserState; |
| 68 infobars::InfoBarManager* infobarManager = |
| 69 InfoBarManagerImpl::FromWebState(webState); |
| 70 DCHECK(infobarManager); |
| 71 ios::ChromeBrowserState* originalBrowserState = |
| 72 browserState->GetOriginalChromeBrowserState(); |
| 73 std::unique_ptr<IdentityProvider> identityProvider( |
| 74 new ProfileIdentityProvider( |
| 75 ios::SigninManagerFactory::GetForBrowserState(originalBrowserState), |
| 76 OAuth2TokenServiceFactory::GetForBrowserState(originalBrowserState), |
| 77 base::Closure())); |
| 78 _autofillClient.reset(new autofill::AutofillClientIOS( |
| 79 browserState, infobarManager, self, passwordGenerationManager, |
| 80 std::move(identityProvider))); |
| 81 autofill::AutofillDriverIOS::CreateForWebStateAndDelegate( |
| 82 webState, _autofillClient.get(), self, |
| 83 GetApplicationContext()->GetApplicationLocale(), |
| 84 downloadEnabled |
| 85 ? autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER |
| 86 : autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER); |
| 87 _autofillAgent = autofillAgent; |
| 88 _autofillManager = |
| 89 autofill::AutofillDriverIOS::FromWebState(webState)->autofill_manager(); |
| 90 } |
| 91 return self; |
| 92 } |
| 93 |
| 94 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState |
| 95 passwordGenerationManager: |
| 96 (password_manager::PasswordGenerationManager*) |
| 97 passwordGenerationManager |
| 98 webState:(web::WebState*)webState { |
| 99 AutofillAgent* autofillAgent = |
| 100 [[AutofillAgent alloc] initWithBrowserState:browserState |
| 101 webState:webState]; |
| 102 return [self initWithBrowserState:browserState |
| 103 webState:webState |
| 104 autofillAgent:autofillAgent |
| 105 passwordGenerationManager:passwordGenerationManager |
| 106 downloadEnabled:YES]; |
| 107 } |
| 108 |
| 109 - (instancetype)init { |
| 110 NOTREACHED(); |
| 111 return nil; |
| 112 } |
| 113 |
| 114 - (void)dealloc { |
| 115 DCHECK(!_autofillAgent); // detachFromWebController must have been called. |
| 116 } |
| 117 |
| 118 - (id<FormSuggestionProvider>)suggestionProvider { |
| 119 return _autofillAgent; |
| 120 } |
| 121 |
| 122 - (void)detachFromWebState { |
| 123 _autofillManager = nullptr; |
| 124 [_autofillAgent detachFromWebState]; |
| 125 _autofillAgent = nil; |
| 126 } |
| 127 |
| 128 #pragma mark - AutofillClientIOSBridge |
| 129 |
| 130 - (void) |
| 131 showAutofillPopup:(const std::vector<autofill::Suggestion>&)popup_suggestions |
| 132 popupDelegate:(const base::WeakPtr<AutofillPopupDelegate>&)delegate { |
| 133 DCHECK( |
| 134 _browserState->GetPrefs()->GetBoolean(autofill::prefs::kAutofillEnabled)); |
| 135 // Convert the suggestions into an NSArray for the keyboard. |
| 136 NSMutableArray* suggestions = [[NSMutableArray alloc] init]; |
| 137 for (size_t i = 0; i < popup_suggestions.size(); ++i) { |
| 138 // In the Chromium implementation the identifiers represent rows on the |
| 139 // drop down of options. These include elements that aren't relevant to us |
| 140 // such as separators ... see blink::WebAutofillClient::MenuItemIDSeparator |
| 141 // for example. We can't include that enum because it's from WebKit, but |
| 142 // fortunately almost all the entries we are interested in (profile or |
| 143 // autofill entries) are zero or positive. The only negative entry we are |
| 144 // interested in is autofill::POPUP_ITEM_ID_CLEAR_FORM, used to show the |
| 145 // "clear form" button. |
| 146 NSString* value = nil; |
| 147 NSString* displayDescription = nil; |
| 148 if (popup_suggestions[i].frontend_id >= 0) { |
| 149 // Value will contain the text to be filled in the selected element while |
| 150 // displayDescription will contain a summary of the data to be filled in |
| 151 // the other elements. |
| 152 value = base::SysUTF16ToNSString(popup_suggestions[i].value); |
| 153 displayDescription = base::SysUTF16ToNSString(popup_suggestions[i].label); |
| 154 } else if (popup_suggestions[i].frontend_id == |
| 155 autofill::POPUP_ITEM_ID_CLEAR_FORM) { |
| 156 // Show the "clear form" button. |
| 157 value = base::SysUTF16ToNSString(popup_suggestions[i].value); |
| 158 } |
| 159 |
| 160 if (!value) |
| 161 continue; |
| 162 |
| 163 FormSuggestion* suggestion = [FormSuggestion |
| 164 suggestionWithValue:value |
| 165 displayDescription:displayDescription |
| 166 icon:base::SysUTF16ToNSString(popup_suggestions[i].icon) |
| 167 identifier:popup_suggestions[i].frontend_id]; |
| 168 [suggestions addObject:suggestion]; |
| 169 } |
| 170 [_autofillAgent onSuggestionsReady:suggestions popupDelegate:delegate]; |
| 171 |
| 172 // The parameter is an optional callback. |
| 173 if (delegate) |
| 174 delegate->OnPopupShown(); |
| 175 } |
| 176 |
| 177 - (void)hideAutofillPopup { |
| 178 [_autofillAgent onSuggestionsReady:@[] |
| 179 popupDelegate:base::WeakPtr<AutofillPopupDelegate>()]; |
| 180 } |
| 181 |
| 182 #pragma mark - AutofillDriverIOSBridge |
| 183 |
| 184 - (void)onFormDataFilled:(uint16_t)query_id |
| 185 result:(const autofill::FormData&)result { |
| 186 DCHECK( |
| 187 _browserState->GetPrefs()->GetBoolean(autofill::prefs::kAutofillEnabled)); |
| 188 [_autofillAgent onFormDataFilled:result]; |
| 189 if (_autofillManager) |
| 190 _autofillManager->OnDidFillAutofillFormData(result, base::TimeTicks::Now()); |
| 191 } |
| 192 |
| 193 - (void)sendAutofillTypePredictionsToRenderer: |
| 194 (const std::vector<autofill::FormStructure*>&)forms { |
| 195 NSUserDefaults* standardDefaults = [NSUserDefaults standardUserDefaults]; |
| 196 if ([standardDefaults boolForKey:@"ShowAutofillTypePredictions"]) |
| 197 [_autofillAgent renderAutofillTypePredictions:forms]; |
| 198 } |
| 199 |
| 200 @end |
OLD | NEW |