| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "chrome/browser/browsing_data/autofill_counter.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <utility> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/memory/scoped_vector.h" | |
| 12 #include "chrome/browser/profiles/profile.h" | |
| 13 #include "chrome/browser/web_data_service_factory.h" | |
| 14 #include "components/autofill/core/browser/autofill_profile.h" | |
| 15 #include "components/autofill/core/browser/credit_card.h" | |
| 16 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" | |
| 17 #include "components/browsing_data/core/pref_names.h" | |
| 18 | |
| 19 AutofillCounter::AutofillCounter(Profile* profile) | |
| 20 : BrowsingDataCounter(browsing_data::prefs::kDeleteFormData), | |
| 21 profile_(profile), | |
| 22 web_data_service_(nullptr), | |
| 23 suggestions_query_(0), | |
| 24 credit_cards_query_(0), | |
| 25 addresses_query_(0), | |
| 26 num_suggestions_(0), | |
| 27 num_credit_cards_(0), | |
| 28 num_addresses_(0) {} | |
| 29 | |
| 30 AutofillCounter::~AutofillCounter() { | |
| 31 CancelAllRequests(); | |
| 32 } | |
| 33 | |
| 34 void AutofillCounter::OnInitialized() { | |
| 35 web_data_service_ = WebDataServiceFactory::GetAutofillWebDataForProfile( | |
| 36 profile_, ServiceAccessType::EXPLICIT_ACCESS); | |
| 37 DCHECK(web_data_service_); | |
| 38 } | |
| 39 | |
| 40 void AutofillCounter::SetPeriodStartForTesting( | |
| 41 const base::Time& period_start_for_testing) { | |
| 42 period_start_for_testing_ = period_start_for_testing; | |
| 43 } | |
| 44 | |
| 45 void AutofillCounter::Count() { | |
| 46 const base::Time start = period_start_for_testing_.is_null() | |
| 47 ? GetPeriodStart() | |
| 48 : period_start_for_testing_; | |
| 49 | |
| 50 CancelAllRequests(); | |
| 51 | |
| 52 // Count the autocomplete suggestions (also called form elements in Autofill). | |
| 53 // Note that |AutofillTable::RemoveFormElementsAddedBetween| only deletes | |
| 54 // those whose entire existence (i.e. the interval between creation time | |
| 55 // and last modified time) lies within the deletion time range. Otherwise, | |
| 56 // it only decreases the count property, but always to a nonzero value, | |
| 57 // and the suggestion is retained. Therefore here as well, we must only count | |
| 58 // the entries that are entirely contained in [start, base::Time::Max()). | |
| 59 // Further, many of these entries may contain the same values, as they are | |
| 60 // simply the same data point entered on different forms. For example, | |
| 61 // [name, value] pairs such as: | |
| 62 // ["mail", "example@example.com"] | |
| 63 // ["email", "example@example.com"] | |
| 64 // ["e-mail", "example@example.com"] | |
| 65 // are stored as three separate entries, but from the user's perspective, | |
| 66 // they constitute the same suggestion - "my email". Therefore, for the final | |
| 67 // output, we will consider all entries with the same value as one suggestion, | |
| 68 // and increment the counter only if all entries with the given value are | |
| 69 // contained in the interval [start, base::Time::Max()). | |
| 70 suggestions_query_ = web_data_service_->GetCountOfValuesContainedBetween( | |
| 71 start, base::Time::Max(), this); | |
| 72 | |
| 73 // Count the credit cards. | |
| 74 credit_cards_query_ = web_data_service_->GetCreditCards(this); | |
| 75 | |
| 76 // Count the addresses. | |
| 77 addresses_query_ = web_data_service_->GetAutofillProfiles(this); | |
| 78 } | |
| 79 | |
| 80 void AutofillCounter::OnWebDataServiceRequestDone( | |
| 81 WebDataServiceBase::Handle handle, const WDTypedResult* result) { | |
| 82 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 83 if (!result) { | |
| 84 CancelAllRequests(); | |
| 85 return; | |
| 86 } | |
| 87 | |
| 88 const base::Time start = period_start_for_testing_.is_null() | |
| 89 ? GetPeriodStart() | |
| 90 : period_start_for_testing_; | |
| 91 | |
| 92 if (handle == suggestions_query_) { | |
| 93 // Autocomplete suggestions. | |
| 94 DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType()); | |
| 95 num_suggestions_ = static_cast<const WDResult<int>*>(result)->GetValue(); | |
| 96 suggestions_query_ = 0; | |
| 97 | |
| 98 } else if (handle == credit_cards_query_) { | |
| 99 // Credit cards. | |
| 100 DCHECK_EQ(AUTOFILL_CREDITCARDS_RESULT, result->GetType()); | |
| 101 const std::vector<autofill::CreditCard*> credit_cards = | |
| 102 static_cast<const WDResult<std::vector<autofill::CreditCard*>>*>( | |
| 103 result)->GetValue(); | |
| 104 | |
| 105 // We own the result from this query. Make sure it will be deleted. | |
| 106 ScopedVector<const autofill::CreditCard> owned_result; | |
| 107 owned_result.assign(credit_cards.begin(), credit_cards.end()); | |
| 108 | |
| 109 num_credit_cards_ = std::count_if( | |
| 110 credit_cards.begin(), | |
| 111 credit_cards.end(), | |
| 112 [start](const autofill::CreditCard* card) { | |
| 113 return card->modification_date() >= start; | |
| 114 }); | |
| 115 credit_cards_query_ = 0; | |
| 116 | |
| 117 } else if (handle == addresses_query_) { | |
| 118 // Addresses. | |
| 119 DCHECK_EQ(AUTOFILL_PROFILES_RESULT, result->GetType()); | |
| 120 const std::vector<autofill::AutofillProfile*> addresses = | |
| 121 static_cast<const WDResult<std::vector<autofill::AutofillProfile*>>*>( | |
| 122 result)->GetValue(); | |
| 123 | |
| 124 // We own the result from this query. Make sure it will be deleted. | |
| 125 ScopedVector<const autofill::AutofillProfile> owned_result; | |
| 126 owned_result.assign(addresses.begin(), addresses.end()); | |
| 127 | |
| 128 num_addresses_ = std::count_if( | |
| 129 addresses.begin(), | |
| 130 addresses.end(), | |
| 131 [start](const autofill::AutofillProfile* address) { | |
| 132 return address->modification_date() >= start; | |
| 133 }); | |
| 134 addresses_query_ = 0; | |
| 135 | |
| 136 } else { | |
| 137 NOTREACHED() << "No such query: " << handle; | |
| 138 } | |
| 139 | |
| 140 // If we still have pending queries, do not report data yet. | |
| 141 if (HasPendingQuery()) | |
| 142 return; | |
| 143 | |
| 144 std::unique_ptr<Result> reported_result(new AutofillResult( | |
| 145 this, num_suggestions_, num_credit_cards_, num_addresses_)); | |
| 146 ReportResult(std::move(reported_result)); | |
| 147 } | |
| 148 | |
| 149 void AutofillCounter::CancelAllRequests() { | |
| 150 if (suggestions_query_) | |
| 151 web_data_service_->CancelRequest(suggestions_query_); | |
| 152 if (credit_cards_query_) | |
| 153 web_data_service_->CancelRequest(credit_cards_query_); | |
| 154 if (addresses_query_) | |
| 155 web_data_service_->CancelRequest(addresses_query_); | |
| 156 } | |
| 157 | |
| 158 // AutofillCounter::AutofillResult --------------------------------------------- | |
| 159 | |
| 160 AutofillCounter::AutofillResult::AutofillResult( | |
| 161 const AutofillCounter* source, | |
| 162 ResultInt num_suggestions, | |
| 163 ResultInt num_credit_cards, | |
| 164 ResultInt num_addresses) | |
| 165 : FinishedResult(source, num_suggestions), | |
| 166 num_credit_cards_(num_credit_cards), | |
| 167 num_addresses_(num_addresses) { | |
| 168 } | |
| 169 | |
| 170 AutofillCounter::AutofillResult::~AutofillResult() { | |
| 171 } | |
| OLD | NEW |