diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
index e3b92654f2a5d3..ce3ab6460e1c54 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -12,6 +12,7 @@
#include "base/values.h"
#include "chrome/browser/autofill/personal_data_manager_factory.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/api/autofill_private/autofill_util.h"
#include "chrome/common/extensions/api/autofill_private.h"
#include "chrome/grit/generated_resources.h"
#include "components/autofill/core/browser/autofill_profile.h"
@@ -299,6 +300,29 @@ ExtensionFunction::ResponseAction
return RespondNow(OneArgument(components.ToValue().release()));
}
+////////////////////////////////////////////////////////////////////////////////
+// AutofillPrivateGetAddressListFunction
+
+AutofillPrivateGetAddressListFunction::AutofillPrivateGetAddressListFunction()
+ : chrome_details_(this) {}
+
+AutofillPrivateGetAddressListFunction::
+ ~AutofillPrivateGetAddressListFunction() {}
+
+ExtensionFunction::ResponseAction AutofillPrivateGetAddressListFunction::Run() {
+ autofill::PersonalDataManager* personal_data =
+ autofill::PersonalDataManagerFactory::GetForProfile(
+ chrome_details_.GetProfile());
+
+ DCHECK(personal_data && personal_data->IsDataLoaded());
+
+ autofill_util::AddressEntryList addressList =
+ extensions::autofill_util::GenerateAddressList(*personal_data);
+
+ return RespondNow(ArgumentList(
+ api::autofill_private::GetAddressList::Results::Create(addressList)));
+}
+
////////////////////////////////////////////////////////////////////////////////
// AutofillPrivateSaveCreditCardFunction
@@ -437,4 +461,30 @@ ExtensionFunction::ResponseAction AutofillPrivateMaskCreditCardFunction::Run() {
return RespondNow(NoArguments());
}
+////////////////////////////////////////////////////////////////////////////////
+// AutofillPrivateGetCreditCardListFunction
+
+AutofillPrivateGetCreditCardListFunction::
+ AutofillPrivateGetCreditCardListFunction()
+ : chrome_details_(this) {}
+
+AutofillPrivateGetCreditCardListFunction::
+ ~AutofillPrivateGetCreditCardListFunction() {}
+
+ExtensionFunction::ResponseAction
+AutofillPrivateGetCreditCardListFunction::Run() {
+ autofill::PersonalDataManager* personal_data =
+ autofill::PersonalDataManagerFactory::GetForProfile(
+ chrome_details_.GetProfile());
+
+ DCHECK(personal_data && personal_data->IsDataLoaded());
+
+ autofill_util::CreditCardEntryList creditCardList =
+ extensions::autofill_util::GenerateCreditCardList(*personal_data);
+
+ return RespondNow(
+ ArgumentList(api::autofill_private::GetCreditCardList::Results::Create(
+ creditCardList)));
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.h b/chrome/browser/extensions/api/autofill_private/autofill_private_api.h
index 819881a2c3ab0a..9a34697c635f8f 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.h
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.h
@@ -48,6 +48,24 @@ class AutofillPrivateGetAddressComponentsFunction :
DISALLOW_COPY_AND_ASSIGN(AutofillPrivateGetAddressComponentsFunction);
};
+class AutofillPrivateGetAddressListFunction : public UIThreadExtensionFunction {
+ public:
+ AutofillPrivateGetAddressListFunction();
+ DECLARE_EXTENSION_FUNCTION("autofillPrivate.getAddressList",
+ AUTOFILLPRIVATE_GETADDRESSLIST);
+
+ protected:
+ ~AutofillPrivateGetAddressListFunction() override;
+
+ // ExtensionFunction overrides.
+ ResponseAction Run() override;
+
+ private:
+ ChromeExtensionFunctionDetails chrome_details_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutofillPrivateGetAddressListFunction);
+};
+
class AutofillPrivateSaveCreditCardFunction : public UIThreadExtensionFunction {
public:
AutofillPrivateSaveCreditCardFunction();
@@ -119,6 +137,25 @@ class AutofillPrivateMaskCreditCardFunction : public UIThreadExtensionFunction {
DISALLOW_COPY_AND_ASSIGN(AutofillPrivateMaskCreditCardFunction);
};
+class AutofillPrivateGetCreditCardListFunction
+ : public UIThreadExtensionFunction {
+ public:
+ AutofillPrivateGetCreditCardListFunction();
+ DECLARE_EXTENSION_FUNCTION("autofillPrivate.getCreditCardList",
+ AUTOFILLPRIVATE_GETCREDITCARDLIST);
+
+ protected:
+ ~AutofillPrivateGetCreditCardListFunction() override;
+
+ // ExtensionFunction overrides.
+ ResponseAction Run() override;
+
+ private:
+ ChromeExtensionFunctionDetails chrome_details_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutofillPrivateGetCreditCardListFunction);
+};
+
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_AUTOFILL_PRIVATE_AUTOFILL_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc
index 5162c97f582b7c..f1fd03426cb934 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc
@@ -40,35 +40,15 @@ AutofillPrivateEventRouter::AutofillPrivateEventRouter(
if (!personal_data_)
return;
- event_router_->RegisterObserver(
- this,
- api::autofill_private::OnAddressListChanged::kEventName);
- event_router_->RegisterObserver(
- this,
- api::autofill_private::OnCreditCardListChanged::kEventName);
- StartOrStopListeningForChanges();
+ personal_data_->AddObserver(this);
}
AutofillPrivateEventRouter::~AutofillPrivateEventRouter() {
}
void AutofillPrivateEventRouter::Shutdown() {
- if (event_router_)
- event_router_->UnregisterObserver(this);
-}
-
-void AutofillPrivateEventRouter::OnListenerAdded(
- const EventListenerInfo& details) {
- // Start listening to change events and propagate the original lists to
- // listeners.
- StartOrStopListeningForChanges();
- OnPersonalDataChanged();
-}
-
-void AutofillPrivateEventRouter::OnListenerRemoved(
- const EventListenerInfo& details) {
- // Stop listening to events if there are no more listeners.
- StartOrStopListeningForChanges();
+ if (personal_data_)
+ personal_data_->RemoveObserver(this);
}
void AutofillPrivateEventRouter::OnPersonalDataChanged() {
@@ -97,25 +77,6 @@ void AutofillPrivateEventRouter::OnPersonalDataChanged() {
event_router_->BroadcastEvent(std::move(extension_event));
}
-void AutofillPrivateEventRouter::StartOrStopListeningForChanges() {
- if (!personal_data_ || !personal_data_->IsDataLoaded())
- return;
-
- bool should_listen_for_address_changes = event_router_->HasEventListener(
- api::autofill_private::OnAddressListChanged::kEventName);
- bool should_listen_for_credit_card_changes = event_router_->HasEventListener(
- api::autofill_private::OnCreditCardListChanged::kEventName);
- bool should_listen = should_listen_for_address_changes ||
- should_listen_for_credit_card_changes;
-
- if (should_listen && !listening_)
- personal_data_->AddObserver(this);
- else if (!should_listen && listening_)
- personal_data_->RemoveObserver(this);
-
- listening_ = should_listen;
-}
-
AutofillPrivateEventRouter* AutofillPrivateEventRouter::Create(
content::BrowserContext* context) {
return new AutofillPrivateEventRouter(context);
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.h b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.h
index 2c435aed5ff9c5..ae00019a47bbba 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.h
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.h
@@ -38,18 +38,10 @@ class AutofillPrivateEventRouter :
// KeyedService overrides:
void Shutdown() override;
- // EventRouter::Observer overrides:
- void OnListenerAdded(const EventListenerInfo& details) override;
- void OnListenerRemoved(const EventListenerInfo& details) override;
-
// PersonalDataManagerObserver implementation.
void OnPersonalDataChanged() override;
private:
- // Either listens or unlistens for changes to |personal_data_|, depending on
- // whether clients are listening to the autofillPrivate API events.
- void StartOrStopListeningForChanges();
-
content::BrowserContext* context_;
EventRouter* event_router_;
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
index 68b70b3836dfc7..364530c6677b6f 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
@@ -37,7 +37,8 @@
-
+
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js
index f0c52b28b6993c..d38235f03cc5fe 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js
@@ -27,10 +27,22 @@ PasswordManager.PlaintextPasswordEvent;
PasswordManager.prototype = {
/**
- * Request the list of saved passwords and observe future changes.
+ * Add an observer to the list of saved passwords.
+ * @param {function(!Array):void} listener
+ */
+ addSavedPasswordListChangedListener: assertNotReached,
+
+ /**
+ * Remove an observer from the list of saved passwords.
+ * @param {function(!Array):void} listener
+ */
+ removeSavedPasswordListChangedListener: assertNotReached,
+
+ /**
+ * Request the list of saved passwords.
* @param {function(!Array):void} callback
*/
- setSavedPasswordListChangedCallback: assertNotReached,
+ getSavedPasswordList: assertNotReached,
/**
* Should remove the saved password and notify that the list has changed.
@@ -40,30 +52,87 @@ PasswordManager.prototype = {
removeSavedPassword: assertNotReached,
/**
- * Request the list of password exceptions and observe future changes.
+ * Add an observer to the list of password exceptions.
+ * @param {function(!Array):void} listener
+ */
+ addExceptionListChangedListener: assertNotReached,
+
+ /**
+ * Remove an observer from the list of password exceptions.
+ * @param {function(!Array):void} listener
+ */
+ removeExceptionListChangedListener: assertNotReached,
+
+ /**
+ * Request the list of password exceptions.
* @param {function(!Array):void} callback
*/
- setExceptionListChangedCallback: assertNotReached,
+ getExceptionList: assertNotReached,
/**
* Should remove the password exception and notify that the list has changed.
* @param {!string} exception The exception that should be removed from the
* list. No-op if |exception| is not in the list.
*/
- removePasswordException: assertNotReached,
+ removeException: assertNotReached,
/**
- * Register a callback for when a password is requested.
- * @param {function(!Array):void} callback
+ * Gets the saved password for a given login pair.
+ * @param {!PasswordManager.LoginPair} loginPair The saved password that
+ * should be retrieved.
+ * @param {function(!PasswordManager.PlaintextPasswordEvent):void} callback
*/
- onPlaintextPasswordRequestedCallback: assertNotReached,
+ getPlaintextPassword: assertNotReached,
+};
+
+/**
+ * Interface for all callbacks to the autofill API.
+ * @interface
+ */
+function AutofillManager() {}
+
+/** @typedef {chrome.autofillPrivate.AddressEntry} */
+AutofillManager.AddressEntry;
+
+/** @typedef {chrome.autofillPrivate.CreditCardEntry} */
+AutofillManager.CreditCardEntry;
+AutofillManager.prototype = {
/**
- * Should request the saved password for a given login pair.
- * @param {!PasswordManager.LoginPair} loginPair The saved password that
- * should be retrieved.
+ * Add an observer to the list of addresses.
+ * @param {function(!Array):void} listener
+ */
+ addAddressListChangedListener: assertNotReached,
+
+ /**
+ * Remove an observer from the list of addresses.
+ * @param {function(!Array):void} listener
*/
- requestPlaintextPassword: assertNotReached,
+ removeAddressListChangedListener: assertNotReached,
+
+ /**
+ * Request the list of addresses.
+ * @param {function(!Array):void} callback
+ */
+ getAddressList: assertNotReached,
+
+ /**
+ * Add an observer to the list of credit cards.
+ * @param {function(!Array):void} listener
+ */
+ addCreditCardListChangedListener: assertNotReached,
+
+ /**
+ * Remove an observer from the list of credit cards.
+ * @param {function(!Array):void} listener
+ */
+ removeCreditCardListChangedListener: assertNotReached,
+
+ /**
+ * Request the list of credit cards.
+ * @param {function(!Array):void} callback
+ */
+ getCreditCardList: assertNotReached,
};
/**
@@ -78,11 +147,19 @@ PasswordManagerImpl.prototype = {
__proto__: PasswordManager,
/** @override */
- setSavedPasswordListChangedCallback: function(callback) {
- // Get the list of passwords...
+ addSavedPasswordListChangedListener: function(listener) {
+ chrome.passwordsPrivate.onSavedPasswordsListChanged.addListener(listener);
+ },
+
+ /** @override */
+ removeSavedPasswordListChangedListener: function(listener) {
+ chrome.passwordsPrivate.onSavedPasswordsListChanged.removeListener(
+ listener);
+ },
+
+ /** @override */
+ getSavedPasswordList: function(callback) {
chrome.passwordsPrivate.getSavedPasswordList(callback);
- // ...and listen for future changes.
- chrome.passwordsPrivate.onSavedPasswordsListChanged.addListener(callback);
},
/** @override */
@@ -91,30 +168,85 @@ PasswordManagerImpl.prototype = {
},
/** @override */
- setExceptionListChangedCallback: function(callback) {
- // Get the list of exceptions...
- chrome.passwordsPrivate.getPasswordExceptionList(callback);
- // ...and listen for future changes.
+ addExceptionListChangedListener: function(listener) {
chrome.passwordsPrivate.onPasswordExceptionsListChanged.addListener(
- callback);
+ listener);
},
/** @override */
- removePasswordException: function(exception) {
- chrome.passwordsPrivate.removePasswordException(exception);
+ removeExceptionListChangedListener: function(listener) {
+ chrome.passwordsPrivate.onPasswordExceptionsListChanged.removeListener(
+ listener);
},
/** @override */
- onPlaintextPasswordRequestedCallback: function(callback) {
- chrome.passwordsPrivate.onPlaintextPasswordRetrieved.addListener(callback);
+ getExceptionList: function(callback) {
+ chrome.passwordsPrivate.getPasswordExceptionList(callback);
},
/** @override */
- requestPlaintextPassword: function(loginPair) {
+ removeException: function(exception) {
+ chrome.passwordsPrivate.removePasswordException(exception);
+ },
+
+ /** @override */
+ getPlaintextPassword: function(loginPair, callback) {
+ var listener = function(reply) {
+ // Only handle the reply for our loginPair request.
+ if (reply.loginPair.originUrl == loginPair.originUrl &&
+ reply.loginPair.username == loginPair.username) {
+ chrome.passwordsPrivate.onPlaintextPasswordRetrieved.removeListener(
+ listener);
+ callback(reply);
+ }
+ };
+ chrome.passwordsPrivate.onPlaintextPasswordRetrieved.addListener(listener);
chrome.passwordsPrivate.requestPlaintextPassword(loginPair);
},
};
+/**
+ * Implementation that accesses the private API.
+ * @implements {AutofillManager}
+ * @constructor
+ */
+function AutofillManagerImpl() {}
+cr.addSingletonGetter(AutofillManagerImpl);
+
+AutofillManagerImpl.prototype = {
+ __proto__: AutofillManager,
+
+ /** @override */
+ addAddressListChangedListener: function(listener) {
+ chrome.autofillPrivate.onAddressListChanged.addListener(listener);
+ },
+
+ /** @override */
+ removeAddressListChangedListener: function(listener) {
+ chrome.autofillPrivate.onAddressListChanged.removeListener(listener);
+ },
+
+ /** @override */
+ getAddressList: function(callback) {
+ chrome.autofillPrivate.getAddressList(callback);
+ },
+
+ /** @override */
+ addCreditCardListChangedListener: function(listener) {
+ chrome.autofillPrivate.onCreditCardListChanged.addListener(listener);
+ },
+
+ /** @override */
+ removeCreditCardListChangedListener: function(listener) {
+ chrome.autofillPrivate.onCreditCardListChanged.removeListener(listener);
+ },
+
+ /** @override */
+ getCreditCardList: function(callback) {
+ chrome.autofillPrivate.getCreditCardList(callback);
+ },
+};
+
(function() {
'use strict';
@@ -144,7 +276,6 @@ Polymer({
*/
savedPasswords: {
type: Array,
- value: function() { return []; },
},
/**
@@ -153,9 +284,24 @@ Polymer({
*/
passwordExceptions: {
type: Array,
- value: function() { return []; },
},
- },
+
+ /**
+ * An array of saved addresses.
+ * @type {!Array}
+ */
+ addresses: {
+ type: Array,
+ },
+
+ /**
+ * An array of saved addresses.
+ * @type {!Array}
+ */
+ creditCards: {
+ type: Array,
+ },
+ },
listeners: {
'remove-password-exception': 'removePasswordException_',
@@ -163,19 +309,68 @@ Polymer({
'show-password': 'showPassword_',
},
+ /** @type {?function(!Array):void} */
+ setSavedPasswordsListener_: null,
+
+ /** @type {?function(!Array):void} */
+ setPasswordExceptionsListener_: null,
+
+ /** @type {?function(!Array)} */
+ setAddressesListener_: null,
+
+ /** @type {?function(!Array)} */
+ setCreditCardsListener_: null,
+
/** @override */
ready: function() {
- this.passwordManager_ = PasswordManagerImpl.getInstance();
-
- this.passwordManager_.setSavedPasswordListChangedCallback(function(list) {
+ // Create listener functions.
+ this.setSavedPasswordsListener_ = function(list) {
this.savedPasswords = list;
- }.bind(this));
- this.passwordManager_.setExceptionListChangedCallback(function(list) {
+ }.bind(this);
+
+ this.setPasswordExceptionsListener_ = function(list) {
this.passwordExceptions = list;
- }.bind(this));
- this.passwordManager_.onPlaintextPasswordRequestedCallback(function(e) {
- this.$$('#passwordSection').setPassword(e.loginPair, e.plaintextPassword);
- }.bind(this));
+ }.bind(this);
+
+ this.setAddressesListener_ = function(list) {
+ this.addresses = list;
+ }.bind(this);
+
+ this.setCreditCardsListener_ = function(list) {
+ this.creditCards = list;
+ }.bind(this);
+
+ // Set the managers. These can be overridden by tests.
+ this.passwordManager_ = PasswordManagerImpl.getInstance();
+ this.autofillManager_ = AutofillManagerImpl.getInstance();
+
+ // Request initial data.
+ this.passwordManager_.getSavedPasswordList(this.setSavedPasswordsListener_);
+ this.passwordManager_.getExceptionList(this.setPasswordExceptionsListener_);
+ this.autofillManager_.getAddressList(this.setAddressesListener_);
+ this.autofillManager_.getCreditCardList(this.setCreditCardsListener_);
+
+ // Listen for changes.
+ this.passwordManager_.addSavedPasswordListChangedListener(
+ this.setSavedPasswordsListener_);
+ this.passwordManager_.addExceptionListChangedListener(
+ this.setPasswordExceptionsListener_);
+ this.autofillManager_.addAddressListChangedListener(
+ this.setAddressesListener_);
+ this.autofillManager_.addCreditCardListChangedListener(
+ this.setCreditCardsListener_);
+ },
+
+ /** @override */
+ detached: function() {
+ this.passwordManager_.removeSavedPasswordListChangedListener(
+ this.setSavedPasswordsListener_);
+ this.passwordManager_.removeExceptionListChangedListener(
+ this.setPasswordExceptionsListener_);
+ this.autofillManager_.removeAddressListChangedListener(
+ this.setAddressesListener_);
+ this.autofillManager_.removeCreditCardListChangedListener(
+ this.setCreditCardsListener_);
},
/**
@@ -184,7 +379,7 @@ Polymer({
* @private
*/
removePasswordException_: function(event) {
- this.passwordManager_.removePasswordException(event.detail);
+ this.passwordManager_.removeException(event.detail);
},
/**
@@ -229,7 +424,9 @@ Polymer({
* @private
*/
showPassword_: function(event) {
- this.passwordManager_.requestPlaintextPassword(event.detail);
+ this.passwordManager_.getPlaintextPassword(event.detail, function(e) {
+ this.$$('#passwordSection').setPassword(e.loginPair, e.plaintextPassword);
+ }.bind(this));
},
});
})();
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 57f46a2cb47ab9..c81bb925863965 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1017,6 +1017,8 @@
'test/data/webui/settings/easy_unlock_browsertest_chromeos.js',
'test/data/webui/settings/languages_page_browsertest.js',
'test/data/webui/settings/on_startup_browsertest.js',
+ 'test/data/webui/settings/passwords_and_autofill_fake_data.js',
+ 'test/data/webui/settings/passwords_and_forms_browsertest.js',
'test/data/webui/settings/settings_autofill_section_browsertest.js',
'test/data/webui/settings/settings_page_browsertest.js',
'test/data/webui/settings/settings_passwords_section_browsertest.js',
diff --git a/chrome/common/extensions/api/autofill_private.idl b/chrome/common/extensions/api/autofill_private.idl
index 43edb3d0d28b0d..b70b6496ca96e9 100644
--- a/chrome/common/extensions/api/autofill_private.idl
+++ b/chrome/common/extensions/api/autofill_private.idl
@@ -165,10 +165,11 @@ namespace autofillPrivate {
DOMString countryCode;
};
- callback GetAddressComponentsCallback =
- void(AddressComponents components);
+ callback GetAddressComponentsCallback = void(AddressComponents components);
+ callback GetAddressListCallback = void(AddressEntry[] entries);
callback ValidatePhoneNumbersCallback =
void(DOMString[] validatedPhoneNumbers);
+ callback GetCreditCardListCallback = void(CreditCardEntry[] entries);
interface Functions {
// Saves the given address. If |address| has an empty string as its ID, it
@@ -186,6 +187,10 @@ namespace autofillPrivate {
static void getAddressComponents(DOMString countryCode,
GetAddressComponentsCallback callback);
+ // Gets the list of addresses.
+ // |callback|: Callback which will be called with the list of addresses.
+ static void getAddressList(GetAddressListCallback callback);
+
// Saves the given credit card. If |card| has an empty string as its
// ID, it will be assigned a new one and added as a new entry.
//
@@ -206,6 +211,10 @@ namespace autofillPrivate {
static void validatePhoneNumbers(ValidatePhoneParams params,
ValidatePhoneNumbersCallback callback);
+ // Gets the list of credit cards.
+ // |callback|: Callback which will be called with the list of credit cards.
+ static void getCreditCardList(GetCreditCardListCallback callback);
+
// Clears the data associated with a wallet card which was saved
// locally so that the saved copy is masked (e.g., "Card ending
// in 1234").
diff --git a/chrome/test/data/extensions/api_test/autofill_private/test.js b/chrome/test/data/extensions/api_test/autofill_private/test.js
index 3097ba0790f4cc..bc4b9ee1394ae6 100644
--- a/chrome/test/data/extensions/api_test/autofill_private/test.js
+++ b/chrome/test/data/extensions/api_test/autofill_private/test.js
@@ -25,6 +25,7 @@ var availableTests = [
}
chrome.autofillPrivate.onAddressListChanged.addListener(handler);
+ chrome.autofillPrivate.getAddressList(handler);
chrome.autofillPrivate.saveAddress({fullNames: [NAME]});
},
@@ -63,6 +64,7 @@ var availableTests = [
}
chrome.autofillPrivate.onCreditCardListChanged.addListener(handler);
+ chrome.autofillPrivate.getCreditCardList(handler);
chrome.autofillPrivate.saveCreditCard({name: NAME});
},
@@ -90,6 +92,7 @@ var availableTests = [
}
chrome.autofillPrivate.onCreditCardListChanged.addListener(handler);
+ chrome.autofillPrivate.getCreditCardList(handler);
chrome.autofillPrivate.saveCreditCard({name: NAME});
},
diff --git a/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js b/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js
new file mode 100644
index 00000000000000..5d4de53de7c9d0
--- /dev/null
+++ b/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js
@@ -0,0 +1,108 @@
+// Copyright 2016 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.
+
+/**
+ * Used to create fake data for both passwords and autofill.
+ * These sections are related, so it made sense to share this.
+ */
+function FakeDataMaker() {}
+/**
+ * Creates a single item for the list of passwords.
+ * @param {string|undefined} url
+ * @param {string|undefined} username
+ * @param {number|undefined} passwordLength
+ * @return {chrome.passwordsPrivate.PasswordUiEntry}
+ */
+FakeDataMaker.passwordEntry = function(url, username, passwordLength) {
+ // Generate fake data if param is undefined.
+ url = url || FakeDataMaker.patternMaker_('www.xxxxxx.com', 16);
+ username = username || FakeDataMaker.patternMaker_('user_xxxxx', 16);
+ passwordLength = passwordLength || Math.floor(Math.random() * 15) + 3;
+
+ return {
+ loginPair: {
+ originUrl: url,
+ username: username,
+ },
+ linkUrl: 'http://' + url + '/login',
+ numCharactersInPassword: passwordLength,
+ };
+};
+
+/**
+ * Creates a single item for the list of password exceptions.
+ * @param {string|undefined} url
+ * @return {chrome.passwordsPrivate.ExceptionPair}
+ */
+FakeDataMaker.exceptionEntry = function(url) {
+ url = url || FakeDataMaker.patternMaker_('www.xxxxxx.com', 16);
+ return {
+ exceptionUrl: url,
+ linkUrl: 'http://' + url + '/login',
+ };
+};
+
+/**
+ * Creates a fake address entry for testing.
+ * @return {!chrome.autofillPrivate.AddressEntry}
+ */
+FakeDataMaker.addressEntry = function() {
+ var ret = {};
+ ret.guid = FakeDataMaker.makeGuid_();
+ ret.fullNames = ['John', 'Doe'];
+ ret.companyName = 'Google';
+ ret.addressLines = FakeDataMaker.patternMaker_('xxxx Main St', 10);
+ ret.addressLevel1 = "CA";
+ ret.addressLevel2 = "Venice";
+ ret.postalCode = FakeDataMaker.patternMaker_('xxxxx', 10);
+ ret.countryCode = 'US';
+ ret.phoneNumbers = [FakeDataMaker.patternMaker_('(xxx) xxx-xxxx', 10)];
+ ret.emailAddresses = [FakeDataMaker.patternMaker_('userxxxx@gmail.com', 16)];
+ ret.languageCode = 'EN-US';
+ ret.metadata = {isLocal: true};
+ ret.metadata.summaryLabel = ret.fullNames[0];
+ ret.metadata.summarySublabel = ' ' + ret.addressLines;
+ return ret;
+};
+
+/**
+ * Creates a new random credit card entry for testing.
+ * @return {!chrome.autofillPrivate.CreditCardEntry}
+ */
+FakeDataMaker.creditCardEntry = function() {
+ var ret = {};
+ ret.guid = FakeDataMaker.makeGuid_();
+ ret.name = 'Jane Doe';
+ ret.cardNumber = FakeDataMaker.patternMaker_('xxxx xxxx xxxx xxxx', 10);
+ ret.expirationMonth = Math.ceil(Math.random() * 11).toString();
+ ret.expirationYear = (2016 + Math.floor(Math.random() * 5)).toString();
+ ret.metadata = {isLocal: true};
+ var cards = ['Visa', 'Mastercard', 'Discover', 'Card'];
+ var card = cards[Math.floor(Math.random() * cards.length)];
+ ret.metadata.summaryLabel = card + ' ' + '****' + ret.cardNumber.substr(-4);
+ return ret;
+};
+
+/**
+ * Creates a new random GUID for testing.
+ * @return {!string}
+ * @private
+ */
+FakeDataMaker.makeGuid_ = function() {
+ return FakeDataMaker.patternMaker_(
+ 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 16);
+};
+
+/**
+ * Replaces any 'x' in a string with a random number of the base.
+ * @param {!string} pattern The pattern that should be used as an input.
+ * @param {!number} base The number base. ie: 16 for hex or 10 for decimal.
+ * @return {!string}
+ * @private
+ */
+FakeDataMaker.patternMaker_ = function(pattern, base) {
+ return pattern.replace(/x/g, function() {
+ return Math.floor(Math.random() * base).toString(base);
+ });
+};
diff --git a/chrome/test/data/webui/settings/passwords_and_forms_browsertest.js b/chrome/test/data/webui/settings/passwords_and_forms_browsertest.js
new file mode 100644
index 00000000000000..b983bc103f6ffa
--- /dev/null
+++ b/chrome/test/data/webui/settings/passwords_and_forms_browsertest.js
@@ -0,0 +1,378 @@
+// Copyright 2016 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.
+
+/** @fileoverview Runs the Polymer Passwords and Forms tests. */
+
+/** @const {string} Path to root from chrome/test/data/webui/settings/. */
+var ROOT_PATH = '../../../../../';
+
+// Polymer BrowserTest fixture.
+GEN_INCLUDE(
+ [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
+
+// Fake data generator.
+GEN_INCLUDE([ROOT_PATH +
+ 'chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js']);
+
+function PasswordManagerExpectations() {};
+PasswordManagerExpectations.prototype = {
+ requested: {
+ passwords: 0,
+ exceptions: 0,
+ plaintextPassword: 0,
+ },
+
+ removed: {
+ passwords: 0,
+ exceptions: 0,
+ },
+
+ listening: {
+ passwords: 0,
+ exceptions: 0,
+ },
+};
+
+/**
+ * Test implementation
+ * @implements {PasswordManager}
+ * @constructor
+ */
+function TestPasswordManager() {
+ this.actual_ = new PasswordManagerExpectations();
+};
+TestPasswordManager.prototype = {
+ /** @override */
+ addSavedPasswordListChangedListener: function(listener) {
+ this.actual_.listening.passwords++;
+ this.lastCallback.addSavedPasswordListChangedListener = listener;
+ },
+
+ /** @override */
+ removeSavedPasswordListChangedListener: function(listener) {
+ this.actual_.listening.passwords--;
+ },
+
+ /** @override */
+ getSavedPasswordList: function(callback) {
+ this.actual_.requested.passwords++;
+ callback(this.data.passwords);
+ },
+
+ /** @override */
+ removeSavedPassword: function(loginPair) {
+ this.actual_.removed.passwords++;
+ },
+
+ /** @override */
+ addExceptionListChangedListener: function(listener) {
+ this.actual_.listening.exceptions++;
+ this.lastCallback.addExceptionListChangedListener = listener;
+ },
+
+ /** @override */
+ removeExceptionListChangedListener: function(listener) {
+ this.actual_.listening.exceptions--;
+ },
+
+ /** @override */
+ getExceptionList: function(callback) {
+ this.actual_.requested.exceptions++;
+ callback(this.data.exceptions);
+ },
+
+ /** @override */
+ removeException: function(exception) {
+ this.actual_.removed.exceptions++;
+ },
+
+ /** @override */
+ getPlaintextPassword: function(loginPair, callback) {
+ this.actual_.requested.plaintextPassword++;
+ this.lastCallback.getPlaintextPassword = callback;
+ },
+
+ /**
+ * Verifies expectations.
+ * @param {!PasswordManagerExpectations} expected
+ */
+ assertExpectations: function(expected) {
+ var actual = this.actual_;
+
+ assertEquals(expected.requested.passwords, actual.requested.passwords);
+ assertEquals(expected.requested.exceptions, actual.requested.exceptions);
+ assertEquals(expected.requested.plaintextPassword,
+ actual.requested.plaintextPassword);
+
+ assertEquals(expected.removed.passwords, actual.removed.passwords);
+ assertEquals(expected.removed.exceptions, actual.removed.exceptions);
+
+ assertEquals(expected.listening.passwords, actual.listening.passwords);
+ assertEquals(expected.listening.exceptions, actual.listening.exceptions);
+ },
+
+ // Set these to have non-empty data.
+ data: {
+ passwords: [],
+ exceptions: [],
+ },
+
+ // Holds the last callbacks so they can be called when needed/
+ lastCallback: {
+ addSavedPasswordListChangedListener: null,
+ addExceptionListChangedListener: null,
+ getPlaintextPassword: null,
+ },
+};
+
+function AutofillManagerExpectations() {};
+AutofillManagerExpectations.prototype = {
+ requested: {
+ addresses: 0,
+ creditCards: 0,
+ },
+
+ listening: {
+ addresses: 0,
+ creditCards: 0,
+ },
+};
+
+/**
+ * Test implementation
+ * @implements {AutofillManager}
+ * @constructor
+ */
+function TestAutofillManager() {
+ this.actual_ = new AutofillManagerExpectations();
+};
+TestAutofillManager.prototype = {
+ /** @override */
+ addAddressListChangedListener: function(listener) {
+ this.actual_.listening.addresses++;
+ this.lastCallback.addAddressListChangedListener = listener;
+ },
+
+ /** @override */
+ removeAddressListChangedListener: function(listener) {
+ this.actual_.listening.addresses--;
+ },
+
+ /** @override */
+ getAddressList: function(callback) {
+ this.actual_.requested.addresses++;
+ callback(this.data.addresses);
+ },
+
+ /** @override */
+ addCreditCardListChangedListener: function(listener) {
+ this.actual_.listening.creditCards++;
+ this.lastCallback.addCreditCardListChangedListener = listener;
+ },
+
+ /** @override */
+ removeCreditCardListChangedListener: function(listener) {
+ this.actual_.listening.creditCards--;
+ },
+
+ /** @override */
+ getCreditCardList: function(callback) {
+ this.actual_.requested.creditCards++;
+ callback(this.data.creditCards);
+ },
+
+ /**
+ * Verifies expectations.
+ * @param {!AutofillManagerExpectations} expected
+ */
+ assertExpectations: function(expected) {
+ var actual = this.actual_;
+
+ assertEquals(expected.requested.addresses, actual.requested.addresses);
+ assertEquals(expected.requested.creditCards, actual.requested.creditCards);
+
+ assertEquals(expected.listening.addresses, actual.listening.addresses);
+ assertEquals(expected.listening.creditCards, actual.listening.creditCards);
+ },
+
+ // Set these to have non-empty data.
+ data: {
+ addresses: [],
+ creditCards: [],
+ },
+
+ // Holds the last callbacks so they can be called when needed/
+ lastCallback: {
+ addAddressListChangedListener: null,
+ addCreditCardListChangedListener: null,
+ },
+};
+
+/**
+ * @constructor
+ * @extends {PolymerTest}
+ */
+function PasswordsAndFormsBrowserTest() {}
+
+PasswordsAndFormsBrowserTest.prototype = {
+ __proto__: PolymerTest.prototype,
+
+ /** @override */
+ browsePreload: 'chrome://md-settings/passwords_and_forms_page/' +
+ 'passwords_and_forms_page.html',
+
+ /** @override */
+ extraLibraries: PolymerTest.getLibraries(ROOT_PATH),
+
+ /** @override */
+ setUp: function() {
+ PolymerTest.prototype.setUp.call(this);
+
+ // Test is run on an individual element that won't have a page language.
+ this.accessibilityAuditConfig.auditRulesToIgnore.push('humanLangMissing');
+
+ // Override the PasswordManagerImpl for testing.
+ this.passwordManager = new TestPasswordManager();
+ PasswordManagerImpl.instance_ = this.passwordManager;
+
+ // Override the AutofillManagerImpl for testing.
+ this.autofillManager = new TestAutofillManager();
+ AutofillManagerImpl.instance_ = this.autofillManager;
+ },
+
+ /**
+ * Creates a new passwords and forms element.
+ * @return {!Object}
+ */
+ createPasswordsAndFormsElement: function() {
+ var element = document.createElement('settings-passwords-and-forms-page');
+ document.body.appendChild(element);
+ Polymer.dom.flush();
+ return element;
+ },
+
+ /**
+ * Creates PasswordManagerExpectations with the values expected after first
+ * creating the element.
+ * @return {!PasswordManagerExpectations}
+ */
+ basePasswordExpectations: function() {
+ var expected = new PasswordManagerExpectations();
+ expected.requested.passwords = 1;
+ expected.requested.exceptions = 1;
+ expected.listening.passwords = 1;
+ expected.listening.exceptions = 1;
+ return expected;
+ },
+
+ /**
+ * Creates AutofillManagerExpectations with the values expected after first
+ * creating the element.
+ * @return {!AutofillManagerExpectations}
+ */
+ baseAutofillExpectations: function() {
+ var expected = new AutofillManagerExpectations();
+ expected.requested.addresses = 1;
+ expected.requested.creditCards = 1;
+ expected.listening.addresses = 1;
+ expected.listening.creditCards = 1;
+ return expected;
+ },
+};
+
+/**
+ * This test will validate that the section is loaded with data.
+ */
+TEST_F('PasswordsAndFormsBrowserTest', 'uiTests', function() {
+ var self = this;
+
+ suite('PasswordsAndForms', function() {
+ test('baseLoadAndRemove', function() {
+ var element = self.createPasswordsAndFormsElement();
+
+ var passwordsExpectations = self.basePasswordExpectations();
+ self.passwordManager.assertExpectations(passwordsExpectations);
+
+ var autofillExpectations = self.baseAutofillExpectations();
+ self.autofillManager.assertExpectations(autofillExpectations);
+
+ element.remove();
+ Polymer.dom.flush();
+
+ passwordsExpectations.listening.passwords = 0;
+ passwordsExpectations.listening.exceptions = 0;
+ self.passwordManager.assertExpectations(passwordsExpectations);
+
+ autofillExpectations.listening.addresses = 0;
+ autofillExpectations.listening.creditCards = 0;
+ self.autofillManager.assertExpectations(autofillExpectations);
+ });
+
+ test('loadPasswordsAsync', function() {
+ var element = self.createPasswordsAndFormsElement();
+
+ var list = [FakeDataMaker.passwordEntry(), FakeDataMaker.passwordEntry()];
+ self.passwordManager.lastCallback.addSavedPasswordListChangedListener(
+ list);
+ Polymer.dom.flush();
+
+ assertEquals(list, element.savedPasswords);
+
+ // The callback is coming from the manager, so the element shouldn't have
+ // additional calls to the manager after the base expectations.
+ self.passwordManager.assertExpectations(self.basePasswordExpectations());
+ self.autofillManager.assertExpectations(self.baseAutofillExpectations());
+ });
+
+ test('loadExceptionsAsync', function() {
+ var element = self.createPasswordsAndFormsElement();
+
+ var list = [FakeDataMaker.exceptionEntry(),
+ FakeDataMaker.exceptionEntry()];
+ self.passwordManager.lastCallback.addExceptionListChangedListener(
+ list);
+ Polymer.dom.flush();
+
+ assertEquals(list, element.passwordExceptions);
+
+ // The callback is coming from the manager, so the element shouldn't have
+ // additional calls to the manager after the base expectations.
+ self.passwordManager.assertExpectations(self.basePasswordExpectations());
+ self.autofillManager.assertExpectations(self.baseAutofillExpectations());
+ });
+
+ test('loadAddressesAsync', function() {
+ var element = self.createPasswordsAndFormsElement();
+
+ var list = [FakeDataMaker.addressEntry(), FakeDataMaker.addressEntry()];
+ self.autofillManager.lastCallback.addAddressListChangedListener(list);
+ Polymer.dom.flush();
+
+ assertEquals(list, element.addresses);
+
+ // The callback is coming from the manager, so the element shouldn't have
+ // additional calls to the manager after the base expectations.
+ self.passwordManager.assertExpectations(self.basePasswordExpectations());
+ self.autofillManager.assertExpectations(self.baseAutofillExpectations());
+ });
+
+ test('loadCreditCardsAsync', function() {
+ var element = self.createPasswordsAndFormsElement();
+
+ var list = [FakeDataMaker.creditCardEntry(),
+ FakeDataMaker.creditCardEntry()];
+ self.autofillManager.lastCallback.addCreditCardListChangedListener(list);
+ Polymer.dom.flush();
+
+ assertEquals(list, element.creditCards);
+
+ // The callback is coming from the manager, so the element shouldn't have
+ // additional calls to the manager after the base expectations.
+ self.passwordManager.assertExpectations(self.basePasswordExpectations());
+ self.autofillManager.assertExpectations(self.baseAutofillExpectations());
+ });
+ });
+
+ mocha.run();
+});
diff --git a/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js b/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js
index ac82b06575c34c..7876c3376c4335 100644
--- a/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js
+++ b/chrome/test/data/webui/settings/settings_autofill_section_browsertest.js
@@ -11,6 +11,10 @@ var ROOT_PATH = '../../../../../';
GEN_INCLUDE(
[ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
+// Fake data generator.
+GEN_INCLUDE([ROOT_PATH +
+ 'chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js']);
+
/**
* @constructor
* @extends {PolymerTest}
@@ -35,71 +39,6 @@ SettingsAutofillSectionBrowserTest.prototype = {
this.accessibilityAuditConfig.auditRulesToIgnore.push('humanLangMissing');
},
- /**
- * Replaces any 'x' in a string with a random number of the base.
- * @param {!string} pattern The pattern that should be used as an input.
- * @param {!number} base The number base. ie: 16 for hex or 10 for decimal.
- * @return {!string}
- * @private
- */
- patternMaker_: function(pattern, base) {
- return pattern.replace(/x/g, function() {
- return Math.floor(Math.random() * base).toString(base);
- });
- },
-
- /**
- * Creates a new random GUID for testing.
- * @return {!string}
- * @private
- */
- makeGuid_: function() {
- return this.patternMaker_('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 16);
- },
-
- /**
- * Creates a fake address entry for testing.
- * @return {!chrome.autofillPrivate.AddressEntry}
- * @private
- */
- createFakeAddressEntry_: function() {
- var ret = {};
- ret.guid = this.makeGuid_();
- ret.fullNames = ['John', 'Doe'];
- ret.companyName = 'Google';
- ret.addressLines = this.patternMaker_('xxxx Main St', 10);
- ret.addressLevel1 = "CA";
- ret.addressLevel2 = "Venice";
- ret.postalCode = this.patternMaker_('xxxxx', 10);
- ret.countryCode = 'US';
- ret.phoneNumbers = [this.patternMaker_('(xxx) xxx-xxxx', 10)];
- ret.emailAddresses = [this.patternMaker_('userxxxx@gmail.com', 16)];
- ret.languageCode = 'EN-US';
- ret.metadata = {isLocal: true};
- ret.metadata.summaryLabel = ret.fullNames[0];
- ret.metadata.summarySublabel = ' ' + ret.addressLines;
- return ret;
- },
-
- /**
- * Creates a new random credit card entry for testing.
- * @return {!chrome.autofillPrivate.CreditCardEntry}
- * @private
- */
- createFakeCreditCardEntry_: function() {
- var ret = {};
- ret.guid = this.makeGuid_();
- ret.name = 'Jane Doe';
- ret.cardNumber = this.patternMaker_('xxxx xxxx xxxx xxxx', 10);
- ret.expirationMonth = Math.ceil(Math.random() * 11).toString();
- ret.expirationYear = (2016 + Math.floor(Math.random() * 5)).toString();
- ret.metadata = {isLocal: true};
- var cards = ['Visa', 'Mastercard', 'Discover', 'Card'];
- var card = cards[Math.floor(Math.random() * cards.length)];
- ret.metadata.summaryLabel = card + ' ' + '****' + ret.cardNumber.substr(-4);
- return ret;
- },
-
/**
* Allow the iron-list to be sized properly.
* @param {!Object} autofillSection
@@ -137,12 +76,12 @@ TEST_F('SettingsAutofillSectionBrowserTest', 'uiTests', function() {
suite('AutofillSection', function() {
test('verifyCreditCardCount', function() {
var creditCards = [
- self.createFakeCreditCardEntry_(),
- self.createFakeCreditCardEntry_(),
- self.createFakeCreditCardEntry_(),
- self.createFakeCreditCardEntry_(),
- self.createFakeCreditCardEntry_(),
- self.createFakeCreditCardEntry_(),
+ FakeDataMaker.creditCardEntry(),
+ FakeDataMaker.creditCardEntry(),
+ FakeDataMaker.creditCardEntry(),
+ FakeDataMaker.creditCardEntry(),
+ FakeDataMaker.creditCardEntry(),
+ FakeDataMaker.creditCardEntry(),
];
var section = self.createAutofillSection_([], creditCards);
@@ -156,7 +95,7 @@ TEST_F('SettingsAutofillSectionBrowserTest', 'uiTests', function() {
});
test('verifyCreditCardFields', function() {
- var creditCard = self.createFakeCreditCardEntry_();
+ var creditCard = FakeDataMaker.creditCardEntry();
var section = self.createAutofillSection_([], [creditCard]);
var creditCardList = section.$.creditCardList;
var row = creditCardList.children[1]; // Skip over the template.
@@ -170,11 +109,11 @@ TEST_F('SettingsAutofillSectionBrowserTest', 'uiTests', function() {
test('verifyAddressCount', function() {
var addresses = [
- self.createFakeAddressEntry_(),
- self.createFakeAddressEntry_(),
- self.createFakeAddressEntry_(),
- self.createFakeAddressEntry_(),
- self.createFakeAddressEntry_(),
+ FakeDataMaker.addressEntry(),
+ FakeDataMaker.addressEntry(),
+ FakeDataMaker.addressEntry(),
+ FakeDataMaker.addressEntry(),
+ FakeDataMaker.addressEntry(),
];
var section = self.createAutofillSection_(addresses, []);
@@ -188,7 +127,7 @@ TEST_F('SettingsAutofillSectionBrowserTest', 'uiTests', function() {
});
test('verifyAddressFields', function() {
- var address = self.createFakeAddressEntry_();
+ var address = FakeDataMaker.addressEntry();
var section = self.createAutofillSection_([address], []);
var addressList = section.$.addressList;
var row = addressList.children[1]; // Skip over the template.
diff --git a/chrome/test/data/webui/settings/settings_passwords_section_browsertest.js b/chrome/test/data/webui/settings/settings_passwords_section_browsertest.js
index 24dbfe6c4112b8..c74d561161d25c 100644
--- a/chrome/test/data/webui/settings/settings_passwords_section_browsertest.js
+++ b/chrome/test/data/webui/settings/settings_passwords_section_browsertest.js
@@ -11,6 +11,10 @@ var ROOT_PATH = '../../../../../';
GEN_INCLUDE(
[ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
+// Fake data generator.
+GEN_INCLUDE([ROOT_PATH +
+ 'chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js']);
+
/**
* @constructor
* @extends {PolymerTest}
@@ -35,35 +39,6 @@ SettingsPasswordSectionBrowserTest.prototype = {
this.accessibilityAuditConfig.auditRulesToIgnore.push('humanLangMissing');
},
- /**
- * Creates a single item for the list of passwords.
- * @param {string} url
- * @param {string} username
- * @param {number} passwordLength
- * @return {chrome.passwordsPrivate.PasswordUiEntry}
- * @private
- */
- createPasswordItem_: function(url, username, passwordLength) {
- return {
- loginPair: {originUrl: url, username: username},
- linkUrl: 'http://' + url + '/login',
- numCharactersInPassword: passwordLength
- };
- },
-
- /**
- * Creates a single item for the list of password exceptions.
- * @param {string} url
- * @return {chrome.passwordsPrivate.ExceptionPair}
- * @private
- */
- createExceptionItem_: function(url) {
- return {
- exceptionUrl: url,
- linkUrl: 'http://' + url + '/login',
- };
- },
-
/**
* Helper method that validates a that elements in the password list match
* the expected data.
@@ -200,12 +175,12 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
assertEquals(self.browsePreload, document.location.href);
var passwordList = [
- self.createPasswordItem_('site1.com', 'luigi', 1),
- self.createPasswordItem_('longwebsite.com', 'peach', 7),
- self.createPasswordItem_('site2.com', 'mario', 70),
- self.createPasswordItem_('site1.com', 'peach', 11),
- self.createPasswordItem_('google.com', 'mario', 7),
- self.createPasswordItem_('site2.com', 'luigi', 8),
+ FakeDataMaker.passwordEntry('site1.com', 'luigi', 1),
+ FakeDataMaker.passwordEntry('longwebsite.com', 'peach', 7),
+ FakeDataMaker.passwordEntry('site2.com', 'mario', 70),
+ FakeDataMaker.passwordEntry('site1.com', 'peach', 11),
+ FakeDataMaker.passwordEntry('google.com', 'mario', 7),
+ FakeDataMaker.passwordEntry('site2.com', 'luigi', 8),
];
var passwordsSection = self.createPasswordsSection_(passwordList, []);
@@ -222,9 +197,9 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
// Test verifies that removing a password will update the elements.
test('verifyPasswordListRemove', function() {
var passwordList = [
- self.createPasswordItem_('anotherwebsite.com', 'luigi', 1),
- self.createPasswordItem_('longwebsite.com', 'peach', 7),
- self.createPasswordItem_('website.com', 'mario', 70)
+ FakeDataMaker.passwordEntry('anotherwebsite.com', 'luigi', 1),
+ FakeDataMaker.passwordEntry('longwebsite.com', 'peach', 7),
+ FakeDataMaker.passwordEntry('website.com', 'mario', 70)
];
var passwordsSection = self.createPasswordsSection_(passwordList, []);
@@ -249,12 +224,12 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
// event. Does not actually remove any passwords.
test('verifyPasswordItemRemoveButton', function(done) {
var passwordList = [
- self.createPasswordItem_('one', 'six', 5),
- self.createPasswordItem_('two', 'five', 3),
- self.createPasswordItem_('three', 'four', 1),
- self.createPasswordItem_('four', 'three', 2),
- self.createPasswordItem_('five', 'two', 4),
- self.createPasswordItem_('six', 'one', 6),
+ FakeDataMaker.passwordEntry('one', 'six', 5),
+ FakeDataMaker.passwordEntry('two', 'five', 3),
+ FakeDataMaker.passwordEntry('three', 'four', 1),
+ FakeDataMaker.passwordEntry('four', 'three', 2),
+ FakeDataMaker.passwordEntry('five', 'two', 4),
+ FakeDataMaker.passwordEntry('six', 'one', 6),
];
var passwordsSection = self.createPasswordsSection_(passwordList, []);
@@ -295,12 +270,12 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
test('verifyPasswordExceptions', function() {
var exceptionList = [
- self.createExceptionItem_('docs.google.com'),
- self.createExceptionItem_('mail.com'),
- self.createExceptionItem_('google.com'),
- self.createExceptionItem_('inbox.google.com'),
- self.createExceptionItem_('maps.google.com'),
- self.createExceptionItem_('plus.google.com'),
+ FakeDataMaker.exceptionEntry('docs.google.com'),
+ FakeDataMaker.exceptionEntry('mail.com'),
+ FakeDataMaker.exceptionEntry('google.com'),
+ FakeDataMaker.exceptionEntry('inbox.google.com'),
+ FakeDataMaker.exceptionEntry('maps.google.com'),
+ FakeDataMaker.exceptionEntry('plus.google.com'),
];
var passwordsSection = self.createPasswordsSection_([], exceptionList);
@@ -318,12 +293,12 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
// Test verifies that removing an exception will update the elements.
test('verifyPasswordExceptionRemove', function() {
var exceptionList = [
- self.createExceptionItem_('docs.google.com'),
- self.createExceptionItem_('mail.com'),
- self.createExceptionItem_('google.com'),
- self.createExceptionItem_('inbox.google.com'),
- self.createExceptionItem_('maps.google.com'),
- self.createExceptionItem_('plus.google.com'),
+ FakeDataMaker.exceptionEntry('docs.google.com'),
+ FakeDataMaker.exceptionEntry('mail.com'),
+ FakeDataMaker.exceptionEntry('google.com'),
+ FakeDataMaker.exceptionEntry('inbox.google.com'),
+ FakeDataMaker.exceptionEntry('maps.google.com'),
+ FakeDataMaker.exceptionEntry('plus.google.com'),
];
var passwordsSection = self.createPasswordsSection_([], exceptionList);
@@ -348,12 +323,12 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
// event. Does not actually remove any exceptions.
test('verifyPasswordExceptionRemoveButton', function(done) {
var exceptionList = [
- self.createExceptionItem_('docs.google.com'),
- self.createExceptionItem_('mail.com'),
- self.createExceptionItem_('google.com'),
- self.createExceptionItem_('inbox.google.com'),
- self.createExceptionItem_('maps.google.com'),
- self.createExceptionItem_('plus.google.com'),
+ FakeDataMaker.exceptionEntry('docs.google.com'),
+ FakeDataMaker.exceptionEntry('mail.com'),
+ FakeDataMaker.exceptionEntry('google.com'),
+ FakeDataMaker.exceptionEntry('inbox.google.com'),
+ FakeDataMaker.exceptionEntry('maps.google.com'),
+ FakeDataMaker.exceptionEntry('plus.google.com'),
];
var passwordsSection = self.createPasswordsSection_([], exceptionList);
@@ -389,7 +364,7 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
test('usePasswordDialogTwice', function() {
var BLANK_PASSWORD = ' ';
- var item = self.createPasswordItem_('google.com', 'homer',
+ var item = FakeDataMaker.passwordEntry('google.com', 'homer',
BLANK_PASSWORD.length);
var passwordDialog = self.createPasswordDialog_(item);
@@ -410,7 +385,7 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
Polymer.dom.flush();
var blankPassword2 = ' '.repeat(17);
- var item2 = self.createPasswordItem_('drive.google.com', 'marge',
+ var item2 = FakeDataMaker.passwordEntry('drive.google.com', 'marge',
blankPassword2.length);
passwordDialog.item = item2;
@@ -430,7 +405,7 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
test('showSavedPassword', function() {
var PASSWORD = 'bAn@n@5';
- var item = self.createPasswordItem_('goo.gl', 'bart', PASSWORD.length);
+ var item = FakeDataMaker.passwordEntry('goo.gl', 'bart', PASSWORD.length);
var passwordDialog = self.createPasswordDialog_(item);
passwordDialog.open();
@@ -450,7 +425,7 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
// Test will timeout if event is not received.
test('onShowSavedPassword', function(done) {
- var item = self.createPasswordItem_('goo.gl', 'bart', 1);
+ var item = FakeDataMaker.passwordEntry('goo.gl', 'bart', 1);
var passwordDialog = self.createPasswordDialog_(item);
passwordDialog.open();
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 1884272d3b4072..f65223b67449f9 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1188,6 +1188,8 @@ enum HistogramValue {
BLUETOOTHLOWENERGY_SENDREQUESTRESPONSE,
BLUETOOTHLOWENERGY_NOTIFYCHARACTERISTICVALUECHANGED,
BLUETOOTHLOWENERGY_REMOVESERVICE,
+ AUTOFILLPRIVATE_GETADDRESSLIST,
+ AUTOFILLPRIVATE_GETCREDITCARDLIST,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY
diff --git a/third_party/closure_compiler/externs/autofill_private.js b/third_party/closure_compiler/externs/autofill_private.js
index dc2f693243f164..61498c832014d6 100644
--- a/third_party/closure_compiler/externs/autofill_private.js
+++ b/third_party/closure_compiler/externs/autofill_private.js
@@ -135,6 +135,14 @@ chrome.autofillPrivate.saveAddress = function(address) {};
*/
chrome.autofillPrivate.getAddressComponents = function(countryCode, callback) {};
+/**
+ * Gets the list of addresses.
+ * @param {function(!Array):void} callback
+ * Callback which will be called with the list of addresses.
+ * @see https://developer.chrome.com/extensions/autofillPrivate#method-getAddressList
+ */
+chrome.autofillPrivate.getAddressList = function(callback) {};
+
/**
* Saves the given credit card. If |card| has an empty string as its ID, it will
* be assigned a new one and added as a new entry.
@@ -162,6 +170,14 @@ chrome.autofillPrivate.removeEntry = function(guid) {};
*/
chrome.autofillPrivate.validatePhoneNumbers = function(params, callback) {};
+/**
+ * Gets the list of credit cards.
+ * @param {function(!Array):void}
+ * callback Callback which will be called with the list of credit cards.
+ * @see https://developer.chrome.com/extensions/autofillPrivate#method-getCreditCardList
+ */
+chrome.autofillPrivate.getCreditCardList = function(callback) {};
+
/**
* Clears the data associated with a wallet card which was saved locally so that
* the saved copy is masked (e.g., "Card ending in 1234").
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 117c618a518207..bc6a233fc9f653 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -71394,6 +71394,8 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
+
+