| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2012 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 #include "components/autofill/browser/autocomplete_history_manager.h" |  | 
| 6 |  | 
| 7 #include <vector> |  | 
| 8 |  | 
| 9 #include "base/prefs/pref_service.h" |  | 
| 10 #include "base/strings/string16.h" |  | 
| 11 #include "base/strings/utf_string_conversions.h" |  | 
| 12 #include "components/autofill/browser/autofill_driver.h" |  | 
| 13 #include "components/autofill/browser/autofill_external_delegate.h" |  | 
| 14 #include "components/autofill/browser/validation.h" |  | 
| 15 #include "components/autofill/core/common/autofill_messages.h" |  | 
| 16 #include "components/autofill/core/common/autofill_pref_names.h" |  | 
| 17 #include "components/autofill/core/common/form_data.h" |  | 
| 18 #include "components/user_prefs/user_prefs.h" |  | 
| 19 #include "content/public/browser/browser_context.h" |  | 
| 20 #include "content/public/browser/render_view_host.h" |  | 
| 21 #include "content/public/browser/web_contents.h" |  | 
| 22 #include "ipc/ipc_message_macros.h" |  | 
| 23 |  | 
| 24 using content::BrowserContext; |  | 
| 25 using content::WebContents; |  | 
| 26 |  | 
| 27 namespace autofill { |  | 
| 28 namespace { |  | 
| 29 |  | 
| 30 // Limit on the number of suggestions to appear in the pop-up menu under an |  | 
| 31 // text input element in a form. |  | 
| 32 const int kMaxAutocompleteMenuItems = 6; |  | 
| 33 |  | 
| 34 bool IsTextField(const FormFieldData& field) { |  | 
| 35   return |  | 
| 36       field.form_control_type == "text" || |  | 
| 37       field.form_control_type == "search" || |  | 
| 38       field.form_control_type == "tel" || |  | 
| 39       field.form_control_type == "url" || |  | 
| 40       field.form_control_type == "email" || |  | 
| 41       field.form_control_type == "text"; |  | 
| 42 } |  | 
| 43 |  | 
| 44 }  // namespace |  | 
| 45 |  | 
| 46 AutocompleteHistoryManager::AutocompleteHistoryManager(AutofillDriver* driver) |  | 
| 47     : browser_context_(driver->GetWebContents()->GetBrowserContext()), |  | 
| 48       driver_(driver), |  | 
| 49       autofill_data_( |  | 
| 50           AutofillWebDataService::FromBrowserContext(browser_context_)), |  | 
| 51       pending_query_handle_(0), |  | 
| 52       query_id_(0), |  | 
| 53       external_delegate_(NULL), |  | 
| 54       send_ipc_(true) { |  | 
| 55   autofill_enabled_.Init( |  | 
| 56       prefs::kAutofillEnabled, |  | 
| 57       user_prefs::UserPrefs::Get(browser_context_)); |  | 
| 58 } |  | 
| 59 |  | 
| 60 AutocompleteHistoryManager::~AutocompleteHistoryManager() { |  | 
| 61   CancelPendingQuery(); |  | 
| 62 } |  | 
| 63 |  | 
| 64 void AutocompleteHistoryManager::OnWebDataServiceRequestDone( |  | 
| 65     WebDataServiceBase::Handle h, |  | 
| 66     const WDTypedResult* result) { |  | 
| 67   DCHECK(pending_query_handle_); |  | 
| 68   pending_query_handle_ = 0; |  | 
| 69 |  | 
| 70   if (!*autofill_enabled_) { |  | 
| 71     SendSuggestions(NULL); |  | 
| 72     return; |  | 
| 73   } |  | 
| 74 |  | 
| 75   DCHECK(result); |  | 
| 76   // Returning early here if |result| is NULL.  We've seen this happen on |  | 
| 77   // Linux due to NFS dismounting and causing sql failures. |  | 
| 78   // See http://crbug.com/68783. |  | 
| 79   if (!result) { |  | 
| 80     SendSuggestions(NULL); |  | 
| 81     return; |  | 
| 82   } |  | 
| 83 |  | 
| 84   DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType()); |  | 
| 85   const WDResult<std::vector<base::string16> >* autofill_result = |  | 
| 86       static_cast<const WDResult<std::vector<base::string16> >*>(result); |  | 
| 87   std::vector<base::string16> suggestions = autofill_result->GetValue(); |  | 
| 88   SendSuggestions(&suggestions); |  | 
| 89 } |  | 
| 90 |  | 
| 91 void AutocompleteHistoryManager::OnGetAutocompleteSuggestions( |  | 
| 92     int query_id, |  | 
| 93     const base::string16& name, |  | 
| 94     const base::string16& prefix, |  | 
| 95     const std::vector<base::string16>& autofill_values, |  | 
| 96     const std::vector<base::string16>& autofill_labels, |  | 
| 97     const std::vector<string16>& autofill_icons, |  | 
| 98     const std::vector<int>& autofill_unique_ids) { |  | 
| 99   CancelPendingQuery(); |  | 
| 100 |  | 
| 101   query_id_ = query_id; |  | 
| 102   autofill_values_ = autofill_values; |  | 
| 103   autofill_labels_ = autofill_labels; |  | 
| 104   autofill_icons_ = autofill_icons; |  | 
| 105   autofill_unique_ids_ = autofill_unique_ids; |  | 
| 106   if (!*autofill_enabled_) { |  | 
| 107     SendSuggestions(NULL); |  | 
| 108     return; |  | 
| 109   } |  | 
| 110 |  | 
| 111   if (autofill_data_.get()) { |  | 
| 112     pending_query_handle_ = autofill_data_->GetFormValuesForElementName( |  | 
| 113         name, prefix, kMaxAutocompleteMenuItems, this); |  | 
| 114   } |  | 
| 115 } |  | 
| 116 |  | 
| 117 void AutocompleteHistoryManager::OnFormSubmitted(const FormData& form) { |  | 
| 118   if (!*autofill_enabled_) |  | 
| 119     return; |  | 
| 120 |  | 
| 121   if (browser_context_->IsOffTheRecord()) |  | 
| 122     return; |  | 
| 123 |  | 
| 124   // Don't save data that was submitted through JavaScript. |  | 
| 125   if (!form.user_submitted) |  | 
| 126     return; |  | 
| 127 |  | 
| 128   // We put the following restriction on stored FormFields: |  | 
| 129   //  - non-empty name |  | 
| 130   //  - non-empty value |  | 
| 131   //  - text field |  | 
| 132   //  - value is not a credit card number |  | 
| 133   //  - value is not a SSN |  | 
| 134   std::vector<FormFieldData> values; |  | 
| 135   for (std::vector<FormFieldData>::const_iterator iter = |  | 
| 136            form.fields.begin(); |  | 
| 137        iter != form.fields.end(); ++iter) { |  | 
| 138     if (!iter->value.empty() && |  | 
| 139         !iter->name.empty() && |  | 
| 140         IsTextField(*iter) && |  | 
| 141         !autofill::IsValidCreditCardNumber(iter->value) && |  | 
| 142         !autofill::IsSSN(iter->value)) { |  | 
| 143       values.push_back(*iter); |  | 
| 144     } |  | 
| 145   } |  | 
| 146 |  | 
| 147   if (!values.empty() && autofill_data_.get()) |  | 
| 148     autofill_data_->AddFormFields(values); |  | 
| 149 } |  | 
| 150 |  | 
| 151 void AutocompleteHistoryManager::OnRemoveAutocompleteEntry( |  | 
| 152     const base::string16& name, const base::string16& value) { |  | 
| 153   if (autofill_data_.get()) |  | 
| 154     autofill_data_->RemoveFormValueForElementName(name, value); |  | 
| 155 } |  | 
| 156 |  | 
| 157 void AutocompleteHistoryManager::SetExternalDelegate( |  | 
| 158     AutofillExternalDelegate* delegate) { |  | 
| 159   external_delegate_ = delegate; |  | 
| 160 } |  | 
| 161 |  | 
| 162 void AutocompleteHistoryManager::CancelPendingQuery() { |  | 
| 163   if (pending_query_handle_) { |  | 
| 164     if (autofill_data_.get()) |  | 
| 165       autofill_data_->CancelRequest(pending_query_handle_); |  | 
| 166     pending_query_handle_ = 0; |  | 
| 167   } |  | 
| 168 } |  | 
| 169 |  | 
| 170 void AutocompleteHistoryManager::SendSuggestions( |  | 
| 171     const std::vector<base::string16>* suggestions) { |  | 
| 172   if (suggestions) { |  | 
| 173     // Combine Autofill and Autocomplete values into values and labels. |  | 
| 174     for (size_t i = 0; i < suggestions->size(); ++i) { |  | 
| 175       bool unique = true; |  | 
| 176       for (size_t j = 0; j < autofill_values_.size(); ++j) { |  | 
| 177         // Don't add duplicate values. |  | 
| 178         if (autofill_values_[j] == (*suggestions)[i]) { |  | 
| 179           unique = false; |  | 
| 180           break; |  | 
| 181         } |  | 
| 182       } |  | 
| 183 |  | 
| 184       if (unique) { |  | 
| 185         autofill_values_.push_back((*suggestions)[i]); |  | 
| 186         autofill_labels_.push_back(base::string16()); |  | 
| 187         autofill_icons_.push_back(base::string16()); |  | 
| 188         autofill_unique_ids_.push_back(0);  // 0 means no profile. |  | 
| 189       } |  | 
| 190     } |  | 
| 191   } |  | 
| 192 |  | 
| 193   if (external_delegate_) { |  | 
| 194     external_delegate_->OnSuggestionsReturned( |  | 
| 195         query_id_, |  | 
| 196         autofill_values_, |  | 
| 197         autofill_labels_, |  | 
| 198         autofill_icons_, |  | 
| 199         autofill_unique_ids_); |  | 
| 200   } else { |  | 
| 201     WebContents* web_contents = driver_->GetWebContents(); |  | 
| 202     if (web_contents && send_ipc_) { |  | 
| 203       web_contents->Send( |  | 
| 204           new AutofillMsg_SuggestionsReturned(web_contents->GetRoutingID(), |  | 
| 205                                               query_id_, |  | 
| 206                                               autofill_values_, |  | 
| 207                                               autofill_labels_, |  | 
| 208                                               autofill_icons_, |  | 
| 209                                               autofill_unique_ids_)); |  | 
| 210     } |  | 
| 211   } |  | 
| 212 |  | 
| 213   query_id_ = 0; |  | 
| 214   autofill_values_.clear(); |  | 
| 215   autofill_labels_.clear(); |  | 
| 216   autofill_icons_.clear(); |  | 
| 217   autofill_unique_ids_.clear(); |  | 
| 218 } |  | 
| 219 |  | 
| 220 }  // namespace autofill |  | 
| OLD | NEW | 
|---|