| Index: ios/chrome/browser/autofill/autofill_controller.mm | 
| diff --git a/ios/chrome/browser/autofill/autofill_controller.mm b/ios/chrome/browser/autofill/autofill_controller.mm | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..196ca15d15434454b6ef214e94b681d78d1e42ab | 
| --- /dev/null | 
| +++ b/ios/chrome/browser/autofill/autofill_controller.mm | 
| @@ -0,0 +1,200 @@ | 
| +// Copyright 2013 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. | 
| + | 
| +#import "ios/chrome/browser/autofill/autofill_controller.h" | 
| + | 
| +#include <stdint.h> | 
| + | 
| +#include <memory> | 
| +#include <utility> | 
| + | 
| +#include "base/strings/sys_string_conversions.h" | 
| +#include "base/strings/utf_string_conversions.h" | 
| +#include "components/autofill/core/browser/autofill_manager.h" | 
| +#include "components/autofill/core/browser/popup_item_ids.h" | 
| +#include "components/autofill/core/common/autofill_pref_names.h" | 
| +#import "components/autofill/ios/browser/autofill_client_ios_bridge.h" | 
| +#include "components/autofill/ios/browser/autofill_driver_ios.h" | 
| +#include "components/autofill/ios/browser/autofill_driver_ios_bridge.h" | 
| +#import "components/autofill/ios/browser/form_suggestion.h" | 
| +#include "components/infobars/core/infobar_manager.h" | 
| +#include "components/pref_registry/pref_registry_syncable.h" | 
| +#include "components/prefs/pref_service.h" | 
| +#include "components/signin/core/browser/profile_identity_provider.h" | 
| +#include "components/signin/core/browser/signin_manager.h" | 
| +#include "ios/chrome/browser/application_context.h" | 
| +#import "ios/chrome/browser/autofill/autofill_agent.h" | 
| +#import "ios/chrome/browser/autofill/form_suggestion_provider.h" | 
| +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 
| +#include "ios/chrome/browser/infobars/infobar_manager_impl.h" | 
| +#include "ios/chrome/browser/pref_names.h" | 
| +#include "ios/chrome/browser/signin/oauth2_token_service_factory.h" | 
| +#include "ios/chrome/browser/signin/signin_manager_factory.h" | 
| +#import "ios/chrome/browser/ui/autofill/autofill_client_ios.h" | 
| +#import "ios/web/public/web_state/web_state.h" | 
| + | 
| +#if !defined(__has_feature) || !__has_feature(objc_arc) | 
| +#error "This file requires ARC support." | 
| +#endif | 
| + | 
| +using autofill::AutofillPopupDelegate; | 
| + | 
| +@interface AutofillController ()<AutofillClientIOSBridge, | 
| +                                 AutofillDriverIOSBridge> { | 
| +  AutofillAgent* _autofillAgent; | 
| +  std::unique_ptr<autofill::AutofillClient> _autofillClient; | 
| +  autofill::AutofillManager* _autofillManager;  // weak | 
| +} | 
| + | 
| +@end | 
| + | 
| +@implementation AutofillController | 
| + | 
| +@synthesize browserState = _browserState; | 
| + | 
| +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState | 
| +                            webState:(web::WebState*)webState | 
| +                       autofillAgent:(AutofillAgent*)autofillAgent | 
| +           passwordGenerationManager: | 
| +               (password_manager::PasswordGenerationManager*) | 
| +                   passwordGenerationManager | 
| +                     downloadEnabled:(BOOL)downloadEnabled { | 
| +  DCHECK(browserState); | 
| +  DCHECK(webState); | 
| +  self = [super init]; | 
| +  if (self) { | 
| +    _browserState = browserState; | 
| +    infobars::InfoBarManager* infobarManager = | 
| +        InfoBarManagerImpl::FromWebState(webState); | 
| +    DCHECK(infobarManager); | 
| +    ios::ChromeBrowserState* originalBrowserState = | 
| +        browserState->GetOriginalChromeBrowserState(); | 
| +    std::unique_ptr<IdentityProvider> identityProvider( | 
| +        new ProfileIdentityProvider( | 
| +            ios::SigninManagerFactory::GetForBrowserState(originalBrowserState), | 
| +            OAuth2TokenServiceFactory::GetForBrowserState(originalBrowserState), | 
| +            base::Closure())); | 
| +    _autofillClient.reset(new autofill::AutofillClientIOS( | 
| +        browserState, infobarManager, self, passwordGenerationManager, | 
| +        std::move(identityProvider))); | 
| +    autofill::AutofillDriverIOS::CreateForWebStateAndDelegate( | 
| +        webState, _autofillClient.get(), self, | 
| +        GetApplicationContext()->GetApplicationLocale(), | 
| +        downloadEnabled | 
| +            ? autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER | 
| +            : autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER); | 
| +    _autofillAgent = autofillAgent; | 
| +    _autofillManager = | 
| +        autofill::AutofillDriverIOS::FromWebState(webState)->autofill_manager(); | 
| +  } | 
| +  return self; | 
| +} | 
| + | 
| +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState | 
| +           passwordGenerationManager: | 
| +               (password_manager::PasswordGenerationManager*) | 
| +                   passwordGenerationManager | 
| +                            webState:(web::WebState*)webState { | 
| +  AutofillAgent* autofillAgent = | 
| +      [[AutofillAgent alloc] initWithBrowserState:browserState | 
| +                                         webState:webState]; | 
| +  return [self initWithBrowserState:browserState | 
| +                           webState:webState | 
| +                      autofillAgent:autofillAgent | 
| +          passwordGenerationManager:passwordGenerationManager | 
| +                    downloadEnabled:YES]; | 
| +} | 
| + | 
| +- (instancetype)init { | 
| +  NOTREACHED(); | 
| +  return nil; | 
| +} | 
| + | 
| +- (void)dealloc { | 
| +  DCHECK(!_autofillAgent);  // detachFromWebController must have been called. | 
| +} | 
| + | 
| +- (id<FormSuggestionProvider>)suggestionProvider { | 
| +  return _autofillAgent; | 
| +} | 
| + | 
| +- (void)detachFromWebState { | 
| +  _autofillManager = nullptr; | 
| +  [_autofillAgent detachFromWebState]; | 
| +  _autofillAgent = nil; | 
| +} | 
| + | 
| +#pragma mark - AutofillClientIOSBridge | 
| + | 
| +- (void) | 
| +showAutofillPopup:(const std::vector<autofill::Suggestion>&)popup_suggestions | 
| +    popupDelegate:(const base::WeakPtr<AutofillPopupDelegate>&)delegate { | 
| +  DCHECK( | 
| +      _browserState->GetPrefs()->GetBoolean(autofill::prefs::kAutofillEnabled)); | 
| +  // Convert the suggestions into an NSArray for the keyboard. | 
| +  NSMutableArray* suggestions = [[NSMutableArray alloc] init]; | 
| +  for (size_t i = 0; i < popup_suggestions.size(); ++i) { | 
| +    // In the Chromium implementation the identifiers represent rows on the | 
| +    // drop down of options. These include elements that aren't relevant to us | 
| +    // such as separators ... see blink::WebAutofillClient::MenuItemIDSeparator | 
| +    // for example. We can't include that enum because it's from WebKit, but | 
| +    // fortunately almost all the entries we are interested in (profile or | 
| +    // autofill entries) are zero or positive. The only negative entry we are | 
| +    // interested in is autofill::POPUP_ITEM_ID_CLEAR_FORM, used to show the | 
| +    // "clear form" button. | 
| +    NSString* value = nil; | 
| +    NSString* displayDescription = nil; | 
| +    if (popup_suggestions[i].frontend_id >= 0) { | 
| +      // Value will contain the text to be filled in the selected element while | 
| +      // displayDescription will contain a summary of the data to be filled in | 
| +      // the other elements. | 
| +      value = base::SysUTF16ToNSString(popup_suggestions[i].value); | 
| +      displayDescription = base::SysUTF16ToNSString(popup_suggestions[i].label); | 
| +    } else if (popup_suggestions[i].frontend_id == | 
| +               autofill::POPUP_ITEM_ID_CLEAR_FORM) { | 
| +      // Show the "clear form" button. | 
| +      value = base::SysUTF16ToNSString(popup_suggestions[i].value); | 
| +    } | 
| + | 
| +    if (!value) | 
| +      continue; | 
| + | 
| +    FormSuggestion* suggestion = [FormSuggestion | 
| +        suggestionWithValue:value | 
| +         displayDescription:displayDescription | 
| +                       icon:base::SysUTF16ToNSString(popup_suggestions[i].icon) | 
| +                 identifier:popup_suggestions[i].frontend_id]; | 
| +    [suggestions addObject:suggestion]; | 
| +  } | 
| +  [_autofillAgent onSuggestionsReady:suggestions popupDelegate:delegate]; | 
| + | 
| +  // The parameter is an optional callback. | 
| +  if (delegate) | 
| +    delegate->OnPopupShown(); | 
| +} | 
| + | 
| +- (void)hideAutofillPopup { | 
| +  [_autofillAgent onSuggestionsReady:@[] | 
| +                       popupDelegate:base::WeakPtr<AutofillPopupDelegate>()]; | 
| +} | 
| + | 
| +#pragma mark - AutofillDriverIOSBridge | 
| + | 
| +- (void)onFormDataFilled:(uint16_t)query_id | 
| +                  result:(const autofill::FormData&)result { | 
| +  DCHECK( | 
| +      _browserState->GetPrefs()->GetBoolean(autofill::prefs::kAutofillEnabled)); | 
| +  [_autofillAgent onFormDataFilled:result]; | 
| +  if (_autofillManager) | 
| +    _autofillManager->OnDidFillAutofillFormData(result, base::TimeTicks::Now()); | 
| +} | 
| + | 
| +- (void)sendAutofillTypePredictionsToRenderer: | 
| +    (const std::vector<autofill::FormStructure*>&)forms { | 
| +  NSUserDefaults* standardDefaults = [NSUserDefaults standardUserDefaults]; | 
| +  if ([standardDefaults boolForKey:@"ShowAutofillTypePredictions"]) | 
| +    [_autofillAgent renderAutofillTypePredictions:forms]; | 
| +} | 
| + | 
| +@end | 
|  |