Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/password_manager/core/browser/form_fetcher_impl.h" | 5 #include "components/password_manager/core/browser/form_fetcher_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "components/autofill/core/common/password_form.h" | 12 #include "components/autofill/core/common/password_form.h" |
| 13 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h" | 13 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h" |
| 14 #include "components/password_manager/core/browser/credentials_filter.h" | 14 #include "components/password_manager/core/browser/credentials_filter.h" |
| 15 #include "components/password_manager/core/browser/password_manager_client.h" | 15 #include "components/password_manager/core/browser/password_manager_client.h" |
| 16 #include "components/password_manager/core/browser/password_manager_util.h" | 16 #include "components/password_manager/core/browser/password_manager_util.h" |
| 17 #include "components/password_manager/core/browser/password_store.h" | 17 #include "components/password_manager/core/browser/password_store.h" |
| 18 #include "components/password_manager/core/browser/psl_matching_helper.h" | |
| 18 #include "components/password_manager/core/browser/statistics_table.h" | 19 #include "components/password_manager/core/browser/statistics_table.h" |
| 19 | 20 |
| 20 using autofill::PasswordForm; | 21 using autofill::PasswordForm; |
| 21 | 22 |
| 22 // Shorten the name to spare line breaks. The code provides enough context | 23 // Shorten the name to spare line breaks. The code provides enough context |
| 23 // already. | 24 // already. |
| 24 using Logger = autofill::SavePasswordProgressLogger; | 25 using Logger = autofill::SavePasswordProgressLogger; |
| 25 | 26 |
| 26 namespace password_manager { | 27 namespace password_manager { |
| 27 | 28 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 39 | 40 |
| 40 // Move out federated matches. | 41 // Move out federated matches. |
| 41 std::vector<std::unique_ptr<PasswordForm>> federated_matches; | 42 std::vector<std::unique_ptr<PasswordForm>> federated_matches; |
| 42 federated_matches.resize(store_results->end() - first_federated); | 43 federated_matches.resize(store_results->end() - first_federated); |
| 43 std::move(first_federated, store_results->end(), federated_matches.begin()); | 44 std::move(first_federated, store_results->end(), federated_matches.begin()); |
| 44 | 45 |
| 45 store_results->erase(first_federated, store_results->end()); | 46 store_results->erase(first_federated, store_results->end()); |
| 46 return federated_matches; | 47 return federated_matches; |
| 47 } | 48 } |
| 48 | 49 |
| 50 void SplitSuppressedFormsAndAssignTo( | |
| 51 const PasswordStore::FormDigest& observed_form_digest, | |
| 52 std::vector<std::unique_ptr<PasswordForm>> suppressed_forms, | |
|
kolos1
2017/05/30 07:02:29
Should we pass |suppressed_forms| by value, by not
engedy
2017/05/30 08:47:43
We do pass it by value.
kolos1
2017/05/30 09:16:36
oops, actually I suggested the opposite. I believe
engedy
2017/05/30 13:51:35
I dunno -- passing it by value allows for std::mov
| |
| 53 std::vector<std::unique_ptr<PasswordForm>>* same_origin_https_forms, | |
| 54 std::vector<std::unique_ptr<PasswordForm>>* psl_matching_forms, | |
| 55 std::vector<std::unique_ptr<PasswordForm>>* same_organization_name_forms) { | |
|
kolos1
2017/05/30 07:02:29
Optional: add DCHECKs for vectors here
engedy
2017/05/30 08:47:43
Done.
| |
| 56 same_origin_https_forms->clear(); | |
| 57 psl_matching_forms->clear(); | |
| 58 same_organization_name_forms->clear(); | |
| 59 for (auto& form : suppressed_forms) { | |
| 60 switch (GetMatchResult(*form, observed_form_digest)) { | |
| 61 case MatchResult::PSL_MATCH: | |
| 62 psl_matching_forms->push_back(std::move(form)); | |
| 63 break; | |
| 64 case MatchResult::NO_MATCH: | |
| 65 if (form->origin.host() != observed_form_digest.origin.host()) { | |
| 66 same_organization_name_forms->push_back(std::move(form)); | |
| 67 } else if (form->origin.SchemeIs(url::kHttpsScheme) && | |
| 68 observed_form_digest.origin.SchemeIs(url::kHttpScheme)) { | |
| 69 same_origin_https_forms->push_back(std::move(form)); | |
| 70 } else { | |
| 71 // HTTP form suppressed on HTTPS observed page: The HTTP->HTTPS | |
| 72 // migration can leave tons of such HTTP forms behind, ignore these. | |
| 73 } | |
| 74 break; | |
| 75 case MatchResult::EXACT_MATCH: | |
| 76 case MatchResult::FEDERATED_MATCH: | |
| 77 case MatchResult::FEDERATED_PSL_MATCH: | |
| 78 NOTREACHED() << "Suppressed match cannot be exact or federated."; | |
| 79 break; | |
| 80 } | |
| 81 } | |
| 82 } | |
| 83 | |
| 49 // Create a vector of const PasswordForm from a vector of | 84 // Create a vector of const PasswordForm from a vector of |
| 50 // unique_ptr<PasswordForm> by applying get() item-wise. | 85 // unique_ptr<PasswordForm> by applying get() item-wise. |
| 51 std::vector<const PasswordForm*> MakeWeakCopies( | 86 std::vector<const PasswordForm*> MakeWeakCopies( |
| 52 const std::vector<std::unique_ptr<PasswordForm>>& owning) { | 87 const std::vector<std::unique_ptr<PasswordForm>>& owning) { |
| 53 std::vector<const PasswordForm*> result(owning.size()); | 88 std::vector<const PasswordForm*> result(owning.size()); |
| 54 std::transform( | 89 std::transform( |
| 55 owning.begin(), owning.end(), result.begin(), | 90 owning.begin(), owning.end(), result.begin(), |
| 56 [](const std::unique_ptr<PasswordForm>& ptr) { return ptr.get(); }); | 91 [](const std::unique_ptr<PasswordForm>& ptr) { return ptr.get(); }); |
| 57 return result; | 92 return result; |
| 58 } | 93 } |
| 59 | 94 |
| 60 // Create a vector of unique_ptr<PasswordForm> from another such vector by | 95 // Create a vector of unique_ptr<PasswordForm> from another such vector by |
| 61 // copying the pointed-to forms. | 96 // copying the pointed-to forms. |
| 62 std::vector<std::unique_ptr<PasswordForm>> MakeCopies( | 97 std::vector<std::unique_ptr<PasswordForm>> MakeCopies( |
| 63 const std::vector<std::unique_ptr<PasswordForm>>& source) { | 98 const std::vector<std::unique_ptr<PasswordForm>>& source) { |
| 64 std::vector<std::unique_ptr<PasswordForm>> result(source.size()); | 99 std::vector<std::unique_ptr<PasswordForm>> result(source.size()); |
| 65 std::transform(source.begin(), source.end(), result.begin(), | 100 std::transform(source.begin(), source.end(), result.begin(), |
| 66 [](const std::unique_ptr<PasswordForm>& ptr) { | 101 [](const std::unique_ptr<PasswordForm>& ptr) { |
| 67 return base::MakeUnique<PasswordForm>(*ptr); | 102 return base::MakeUnique<PasswordForm>(*ptr); |
| 68 }); | 103 }); |
| 69 return result; | 104 return result; |
| 70 } | 105 } |
| 71 | 106 |
| 72 } // namespace | 107 } // namespace |
| 73 | 108 |
| 74 FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest, | 109 FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest, |
| 75 const PasswordManagerClient* client, | 110 const PasswordManagerClient* client, |
| 76 bool should_migrate_http_passwords, | 111 bool should_migrate_http_passwords, |
| 77 bool should_query_suppressed_https_forms) | 112 bool should_query_suppressed_forms) |
| 78 : form_digest_(std::move(form_digest)), | 113 : form_digest_(std::move(form_digest)), |
| 79 client_(client), | 114 client_(client), |
| 80 should_migrate_http_passwords_(should_migrate_http_passwords), | 115 should_migrate_http_passwords_(should_migrate_http_passwords), |
| 81 should_query_suppressed_https_forms_( | 116 should_query_suppressed_forms_(should_query_suppressed_forms) {} |
| 82 should_query_suppressed_https_forms) {} | |
| 83 | 117 |
| 84 FormFetcherImpl::~FormFetcherImpl() = default; | 118 FormFetcherImpl::~FormFetcherImpl() = default; |
| 85 | 119 |
| 86 void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) { | 120 void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) { |
| 87 DCHECK(consumer); | 121 DCHECK(consumer); |
| 88 consumers_.insert(consumer); | 122 consumers_.insert(consumer); |
| 89 if (state_ == State::NOT_WAITING) | 123 if (state_ == State::NOT_WAITING) |
| 90 consumer->ProcessMatches(weak_non_federated_, filtered_count_); | 124 consumer->ProcessMatches(weak_non_federated_, filtered_count_); |
| 91 } | 125 } |
| 92 | 126 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 104 return interactions_stats_; | 138 return interactions_stats_; |
| 105 } | 139 } |
| 106 | 140 |
| 107 const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches() | 141 const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches() |
| 108 const { | 142 const { |
| 109 return weak_federated_; | 143 return weak_federated_; |
| 110 } | 144 } |
| 111 | 145 |
| 112 const std::vector<const PasswordForm*>& | 146 const std::vector<const PasswordForm*>& |
| 113 FormFetcherImpl::GetSuppressedHTTPSForms() const { | 147 FormFetcherImpl::GetSuppressedHTTPSForms() const { |
| 114 return weak_suppressed_https_forms_; | 148 return weak_suppressed_same_origin_https_forms_; |
| 115 } | 149 } |
| 116 | 150 |
| 117 bool FormFetcherImpl::DidCompleteQueryingSuppressedHTTPSForms() const { | 151 const std::vector<const PasswordForm*>& |
| 118 return did_complete_querying_suppressed_https_forms_; | 152 FormFetcherImpl::GetSuppressedPSLMatchingForms() const { |
| 153 return weak_suppressed_psl_matching_forms_; | |
| 154 } | |
| 155 | |
| 156 const std::vector<const PasswordForm*>& | |
| 157 FormFetcherImpl::GetSuppressedSameOrganizationNameForms() const { | |
| 158 return weak_suppressed_same_organization_name_forms_; | |
| 159 } | |
| 160 | |
| 161 bool FormFetcherImpl::DidCompleteQueryingSuppressedForms() const { | |
| 162 return did_complete_querying_suppressed_forms_; | |
| 119 } | 163 } |
| 120 | 164 |
| 121 void FormFetcherImpl::OnGetPasswordStoreResults( | 165 void FormFetcherImpl::OnGetPasswordStoreResults( |
| 122 std::vector<std::unique_ptr<PasswordForm>> results) { | 166 std::vector<std::unique_ptr<PasswordForm>> results) { |
| 123 DCHECK_EQ(State::WAITING, state_); | 167 DCHECK_EQ(State::WAITING, state_); |
| 124 | 168 |
| 125 if (need_to_refetch_) { | 169 if (need_to_refetch_) { |
| 126 // The received results are no longer up to date, need to re-request. | 170 // The received results are no longer up to date, need to re-request. |
| 127 state_ = State::NOT_WAITING; | 171 state_ = State::NOT_WAITING; |
| 128 Fetch(); | 172 Fetch(); |
| 129 need_to_refetch_ = false; | 173 need_to_refetch_ = false; |
| 130 return; | 174 return; |
| 131 } | 175 } |
| 132 | 176 |
| 133 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; | 177 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; |
| 134 if (password_manager_util::IsLoggingActive(client_)) { | 178 if (password_manager_util::IsLoggingActive(client_)) { |
| 135 logger.reset( | 179 logger.reset( |
| 136 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); | 180 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); |
| 137 logger->LogMessage(Logger::STRING_ON_GET_STORE_RESULTS_METHOD); | 181 logger->LogMessage(Logger::STRING_ON_GET_STORE_RESULTS_METHOD); |
| 138 logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size()); | 182 logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size()); |
| 139 } | 183 } |
| 140 | 184 |
| 141 // If this is a non-secure Web origin (i.e. HTTP), kick off the discovery of | 185 // If this is a non-secure Web origin (i.e. HTTP), kick off the discovery of |
|
kolos1
2017/05/30 07:02:29
I believe we should change the comment.
engedy
2017/05/30 08:47:43
Oh yes. Done.
| |
| 142 // credentials stored for the secure version of this origin (i.e. HTTPS), | 186 // credentials stored for the secure version of this origin (i.e. HTTPS), |
| 143 // regardless of whether there are some precisely matching |results|. | 187 // regardless of whether there are some precisely matching |results|. |
| 144 // | 188 // |
| 145 // These results are used only for recording metrics at PasswordFormManager | 189 // These results are used only for recording metrics at PasswordFormManager |
| 146 // desctruction time, this is why they are requested so late. | 190 // desctruction time, this is why they are requested so late. |
| 147 if (should_query_suppressed_https_forms_ && | 191 if (should_query_suppressed_forms_ && |
| 148 form_digest_.scheme == PasswordForm::SCHEME_HTML && | 192 form_digest_.scheme == PasswordForm::SCHEME_HTML && |
| 149 form_digest_.origin.SchemeIs(url::kHttpScheme)) { | 193 GURL(form_digest_.signon_realm).SchemeIsHTTPOrHTTPS()) { |
| 150 suppressed_https_form_fetcher_ = | 194 suppressed_form_fetcher_ = base::MakeUnique<SuppressedFormFetcher>( |
| 151 base::MakeUnique<SuppressedHTTPSFormFetcher>(form_digest_.signon_realm, | 195 form_digest_.signon_realm, client_, this); |
| 152 client_, this); | |
| 153 } | 196 } |
| 154 | 197 |
| 155 if (should_migrate_http_passwords_ && results.empty() && | 198 if (should_migrate_http_passwords_ && results.empty() && |
| 156 form_digest_.origin.SchemeIs(url::kHttpsScheme)) { | 199 form_digest_.origin.SchemeIs(url::kHttpsScheme)) { |
| 157 http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( | 200 http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( |
| 158 form_digest_.origin, client_, this); | 201 form_digest_.origin, client_, this); |
| 159 return; | 202 return; |
| 160 } | 203 } |
| 161 | 204 |
| 162 ProcessPasswordStoreResults(std::move(results)); | 205 ProcessPasswordStoreResults(std::move(results)); |
| 163 } | 206 } |
| 164 | 207 |
| 165 void FormFetcherImpl::OnGetSiteStatistics( | 208 void FormFetcherImpl::OnGetSiteStatistics( |
| 166 std::vector<InteractionsStats> stats) { | 209 std::vector<InteractionsStats> stats) { |
| 167 // On Windows the password request may be resolved after the statistics due to | 210 // On Windows the password request may be resolved after the statistics due to |
| 168 // importing from IE. | 211 // importing from IE. |
| 169 interactions_stats_ = std::move(stats); | 212 interactions_stats_ = std::move(stats); |
| 170 } | 213 } |
| 171 | 214 |
| 172 void FormFetcherImpl::ProcessMigratedForms( | 215 void FormFetcherImpl::ProcessMigratedForms( |
| 173 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { | 216 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { |
| 174 ProcessPasswordStoreResults(std::move(forms)); | 217 ProcessPasswordStoreResults(std::move(forms)); |
| 175 } | 218 } |
| 176 | 219 |
| 177 void FormFetcherImpl::ProcessSuppressedHTTPSForms( | 220 void FormFetcherImpl::ProcessSuppressedForms( |
| 178 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { | 221 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { |
| 179 did_complete_querying_suppressed_https_forms_ = true; | 222 did_complete_querying_suppressed_forms_ = true; |
| 180 | 223 SplitSuppressedFormsAndAssignTo(form_digest_, std::move(forms), |
| 181 suppressed_https_forms_ = std::move(forms); | 224 &suppressed_same_origin_https_forms_, |
| 182 weak_suppressed_https_forms_ = MakeWeakCopies(suppressed_https_forms_); | 225 &suppressed_psl_matching_forms_, |
| 226 &suppressed_same_organization_name_forms_); | |
| 227 weak_suppressed_same_origin_https_forms_ = | |
| 228 MakeWeakCopies(suppressed_same_origin_https_forms_); | |
| 229 weak_suppressed_psl_matching_forms_ = | |
| 230 MakeWeakCopies(suppressed_psl_matching_forms_); | |
| 231 weak_suppressed_same_organization_name_forms_ = | |
| 232 MakeWeakCopies(suppressed_same_organization_name_forms_); | |
| 183 } | 233 } |
| 184 | 234 |
| 185 void FormFetcherImpl::Fetch() { | 235 void FormFetcherImpl::Fetch() { |
| 186 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; | 236 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; |
| 187 if (password_manager_util::IsLoggingActive(client_)) { | 237 if (password_manager_util::IsLoggingActive(client_)) { |
| 188 logger.reset( | 238 logger.reset( |
| 189 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); | 239 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); |
| 190 logger->LogMessage(Logger::STRING_FETCH_METHOD); | 240 logger->LogMessage(Logger::STRING_FETCH_METHOD); |
| 191 logger->LogNumber(Logger::STRING_FORM_FETCHER_STATE, | 241 logger->LogNumber(Logger::STRING_FORM_FETCHER_STATE, |
| 192 static_cast<int>(state_)); | 242 static_cast<int>(state_)); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 216 password_store->GetSiteStats(form_digest_.origin.GetOrigin(), this); | 266 password_store->GetSiteStats(form_digest_.origin.GetOrigin(), this); |
| 217 #endif | 267 #endif |
| 218 } | 268 } |
| 219 | 269 |
| 220 std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() { | 270 std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() { |
| 221 DCHECK_EQ(State::NOT_WAITING, state_); | 271 DCHECK_EQ(State::NOT_WAITING, state_); |
| 222 | 272 |
| 223 // Create the copy without the "HTTPS migration" activated. If it was needed, | 273 // Create the copy without the "HTTPS migration" activated. If it was needed, |
| 224 // then it was done by |this| already. | 274 // then it was done by |this| already. |
| 225 auto result = base::MakeUnique<FormFetcherImpl>( | 275 auto result = base::MakeUnique<FormFetcherImpl>( |
| 226 form_digest_, client_, false, should_query_suppressed_https_forms_); | 276 form_digest_, client_, false, should_query_suppressed_forms_); |
|
kolos1
2017/05/30 07:02:29
Shall we create a copy with SuppressedFormsFetcher
engedy
2017/05/30 08:47:43
The SuppressedFormFetcher has no state, so I guess
kolos1
2017/05/30 09:16:36
Sorry for confusing comment again :(
HTTP migrati
engedy
2017/05/30 13:51:35
Added a unittest to enforce that no fetch is made
| |
| 227 | 277 |
| 228 result->non_federated_ = MakeCopies(this->non_federated_); | 278 result->non_federated_ = MakeCopies(this->non_federated_); |
| 229 result->federated_ = MakeCopies(this->federated_); | 279 result->federated_ = MakeCopies(this->federated_); |
| 230 result->interactions_stats_ = this->interactions_stats_; | 280 result->interactions_stats_ = this->interactions_stats_; |
| 231 result->suppressed_https_forms_ = MakeCopies(this->suppressed_https_forms_); | 281 result->suppressed_same_origin_https_forms_ = |
| 282 MakeCopies(this->suppressed_same_origin_https_forms_); | |
| 283 result->suppressed_psl_matching_forms_ = | |
| 284 MakeCopies(this->suppressed_psl_matching_forms_); | |
| 285 result->suppressed_same_organization_name_forms_ = | |
| 286 MakeCopies(this->suppressed_same_organization_name_forms_); | |
| 232 | 287 |
| 233 result->weak_non_federated_ = MakeWeakCopies(result->non_federated_); | 288 result->weak_non_federated_ = MakeWeakCopies(result->non_federated_); |
| 234 result->weak_federated_ = MakeWeakCopies(result->federated_); | 289 result->weak_federated_ = MakeWeakCopies(result->federated_); |
| 235 result->weak_suppressed_https_forms_ = | 290 result->weak_suppressed_same_origin_https_forms_ = |
| 236 MakeWeakCopies(result->suppressed_https_forms_); | 291 MakeWeakCopies(result->suppressed_same_origin_https_forms_); |
| 292 result->weak_suppressed_psl_matching_forms_ = | |
| 293 MakeWeakCopies(result->suppressed_psl_matching_forms_); | |
| 294 result->weak_suppressed_same_organization_name_forms_ = | |
| 295 MakeWeakCopies(result->suppressed_same_organization_name_forms_); | |
| 237 | 296 |
| 238 result->filtered_count_ = this->filtered_count_; | 297 result->filtered_count_ = this->filtered_count_; |
| 239 result->state_ = this->state_; | 298 result->state_ = this->state_; |
| 240 result->need_to_refetch_ = this->need_to_refetch_; | 299 result->need_to_refetch_ = this->need_to_refetch_; |
| 241 | 300 |
| 242 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required. | 301 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required. |
| 243 return std::move(result); | 302 return std::move(result); |
| 244 } | 303 } |
| 245 | 304 |
| 246 void FormFetcherImpl::ProcessPasswordStoreResults( | 305 void FormFetcherImpl::ProcessPasswordStoreResults( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 258 filtered_count_ = original_count - non_federated_.size(); | 317 filtered_count_ = original_count - non_federated_.size(); |
| 259 | 318 |
| 260 weak_non_federated_ = MakeWeakCopies(non_federated_); | 319 weak_non_federated_ = MakeWeakCopies(non_federated_); |
| 261 weak_federated_ = MakeWeakCopies(federated_); | 320 weak_federated_ = MakeWeakCopies(federated_); |
| 262 | 321 |
| 263 for (FormFetcher::Consumer* consumer : consumers_) | 322 for (FormFetcher::Consumer* consumer : consumers_) |
| 264 consumer->ProcessMatches(weak_non_federated_, filtered_count_); | 323 consumer->ProcessMatches(weak_non_federated_, filtered_count_); |
| 265 } | 324 } |
| 266 | 325 |
| 267 } // namespace password_manager | 326 } // namespace password_manager |
| OLD | NEW |