[AF] Schedule Add/Remove/Update profiles

Keep a timely ordered list of requested operations on profiles.
For each profile, start the next operation when the previous one
finishes on the database.

Also, profile_validities_need_update_ will be updated only for
add/update.
Note: For different profiles, there is no overlap, therefore,
operations can be handled in parallel. This is especially useful for
async tasks such as client side validation.

Bug: 909730
Change-Id: I822648a71e7cfd815461149645d3411f6d08ba9e
Reviewed-on: https://chromium-review.googlesource.com/c/1372175
Reviewed-by: Tatiana Gornak <melandory@chromium.org>
Reviewed-by: Martin Šrámek <msramek@chromium.org>
Reviewed-by: Roger McFarlane <rogerm@chromium.org>
Commit-Queue: Parastoo Geranmayeh <parastoog@google.com>
Cr-Commit-Position: refs/heads/master@{#620323}
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index 80d3c08..6c85224 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -142,7 +142,7 @@
   // The function returns after the PersonalDataManager is updated.
   void FillFormAndSubmit(const std::string& filename, const FormMap& data) {
     FillFormAndSubmitWithHandler(filename, data, kDocumentClickHandlerSubmitJS,
-                                 true, true);
+                                 true);
   }
 
   // Helper where the actual submit JS code can be specified, as well as whether
@@ -150,16 +150,13 @@
   void FillFormAndSubmitWithHandler(const std::string& filename,
                                     const FormMap& data,
                                     const std::string& submit_js,
-                                    bool simulate_click,
-                                    bool expect_personal_data_change) {
+                                    bool simulate_click) {
     GURL url = embedded_test_server()->GetURL("/autofill/" + filename);
     NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
     params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
     ui_test_utils::NavigateToURL(&params);
 
-    std::unique_ptr<WindowedPersonalDataManagerObserver> observer;
-    if (expect_personal_data_change)
-      observer.reset(new WindowedPersonalDataManagerObserver(browser()));
+    WindowedPersonalDataManagerObserver observer(browser());
 
     std::string js = GetJSToFillForm(data) + submit_js;
     ASSERT_TRUE(content::ExecuteScript(web_contents(), js));
@@ -170,11 +167,7 @@
           browser()->tab_strip_model()->GetActiveWebContents(), 0,
           blink::WebMouseEvent::Button::kLeft);
     }
-    // We may not always be expecting changes in Personal data.
-    if (observer.get())
-      observer->Wait();
-    else
-      base::RunLoop().RunUntilIdle();
+    observer.Wait();
   }
 
   // Aggregate profiles from forms into Autofill preferences. Returns the number
@@ -255,7 +248,7 @@
 
   std::string submit("document.forms[0].submit();");
   FillFormAndSubmitWithHandler("duplicate_profiles_test.html", data, submit,
-                               false, true);
+                               false);
 
   ASSERT_EQ(1u, personal_data_manager()->GetProfiles().size());
 }
@@ -276,7 +269,7 @@
       "document.forms[0].addEventListener('submit', preventFunction);"
       "document.querySelector('input[type=submit]').click();");
   FillFormAndSubmitWithHandler("duplicate_profiles_test.html", data, submit,
-                               false, false);
+                               false);
 
   // The AutofillManager will update the user's profile.
   EXPECT_EQ(1u, personal_data_manager()->GetProfiles().size());
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index 2b507eb..be047438 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -820,19 +820,32 @@
 
 }  // namespace
 
+ACTION(QuitMainMessageLoop) {
+  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+}
+
+class PersonalDataLoadedObserverMock
+    : public autofill::PersonalDataManagerObserver {
+ public:
+  PersonalDataLoadedObserverMock() {}
+  ~PersonalDataLoadedObserverMock() override {}
+  MOCK_METHOD0(OnPersonalDataChanged, void());
+  MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void());
+};
+
 // RemoveAutofillTester is not a part of the anonymous namespace above, as
 // PersonalDataManager declares it a friend in an empty namespace.
-class RemoveAutofillTester : public autofill::PersonalDataManagerObserver {
+class RemoveAutofillTester {
  public:
   explicit RemoveAutofillTester(TestingProfile* profile)
       : personal_data_manager_(
             autofill::PersonalDataManagerFactory::GetForProfile(profile)) {
     autofill::test::DisableSystemServices(profile->GetPrefs());
-    personal_data_manager_->AddObserver(this);
+    personal_data_manager_->AddObserver(&personal_data_observer_);
   }
 
-  ~RemoveAutofillTester() override {
-    personal_data_manager_->RemoveObserver(this);
+  ~RemoveAutofillTester() {
+    personal_data_manager_->RemoveObserver(&personal_data_observer_);
     autofill::test::ReenableSystemServices();
   }
 
@@ -880,7 +893,8 @@
     profiles.push_back(profile);
 
     personal_data_manager_->SetProfiles(&profiles);
-    base::TaskScheduler::GetInstance()->FlushForTesting();
+
+    WaitForOnPersonalDataFinishedProfileTasks();
 
     std::vector<autofill::CreditCard> cards;
     autofill::CreditCard card;
@@ -895,15 +909,24 @@
     cards.push_back(card);
 
     personal_data_manager_->SetCreditCards(&cards);
-    base::TaskScheduler::GetInstance()->FlushForTesting();
+    WaitForOnPersonalDataChanged();
   }
 
  private:
-  void OnPersonalDataChanged() override {
-    base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  void WaitForOnPersonalDataChanged() {
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+        .WillRepeatedly(QuitMainMessageLoop());
+    base::RunLoop().Run();
+  }
+
+  void WaitForOnPersonalDataFinishedProfileTasks() {
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillRepeatedly(QuitMainMessageLoop());
+    base::RunLoop().Run();
   }
 
   autofill::PersonalDataManager* personal_data_manager_;
+  PersonalDataLoadedObserverMock personal_data_observer_;
   DISALLOW_COPY_AND_ASSIGN(RemoveAutofillTester);
 };
 
diff --git a/chrome/browser/sync/test/integration/autofill_helper.cc b/chrome/browser/sync/test/integration/autofill_helper.cc
index 8629fbb..3da2bb0 100644
--- a/chrome/browser/sync/test/integration/autofill_helper.cc
+++ b/chrome/browser/sync/test/integration/autofill_helper.cc
@@ -160,6 +160,10 @@
 
 namespace autofill_helper {
 
+ACTION_P(QuitMessageLoop, loop) {
+  loop->Quit();
+}
+
 AutofillProfile CreateAutofillProfile(ProfileType type) {
   AutofillProfile profile;
   switch (type) {
@@ -269,7 +273,20 @@
 }
 
 void SetProfiles(int profile, std::vector<AutofillProfile>* autofill_profiles) {
-  GetPersonalDataManager(profile)->SetProfiles(autofill_profiles);
+  PersonalDataLoadedObserverMock personal_data_observer;
+  PersonalDataManager* pdm = GetPersonalDataManager(profile);
+  base::RunLoop run_loop;
+
+  pdm->AddObserver(&personal_data_observer);
+  EXPECT_CALL(personal_data_observer, OnPersonalDataFinishedProfileTasks())
+      .WillOnce(QuitMessageLoop(&run_loop));
+  EXPECT_CALL(personal_data_observer, OnPersonalDataChanged())
+      .Times(testing::AnyNumber());
+
+  pdm->SetProfiles(autofill_profiles);
+
+  run_loop.Run();
+  pdm->RemoveObserver(&personal_data_observer);
 }
 
 void SetCreditCards(int profile, std::vector<CreditCard>* credit_cards) {
@@ -310,8 +327,16 @@
 }
 
 std::vector<AutofillProfile*> GetAllAutoFillProfiles(int profile) {
+  PersonalDataLoadedObserverMock personal_data_observer;
+  base::RunLoop run_loop;
+
   PersonalDataManager* pdm = GetPersonalDataManager(profile);
+  pdm->AddObserver(&personal_data_observer);
+
   pdm->Refresh();
+  EXPECT_CALL(personal_data_observer, OnPersonalDataFinishedProfileTasks())
+      .WillOnce(QuitMessageLoop(&run_loop));
+  EXPECT_CALL(personal_data_observer, OnPersonalDataChanged()).Times(1);
 
   // PersonalDataManager::GetProfiles() simply returns the current values that
   // have been last reported to the UI sequence. PersonalDataManager::Refresh()
@@ -328,6 +353,8 @@
   // cancel outstanding queries, this is only instigated on the UI sequence,
   // which we are about to block, which means we are safe.
   WaitForCurrentTasksToComplete(GetWebDataService(profile)->GetDBTaskRunner());
+  run_loop.Run();
+  pdm->RemoveObserver(&personal_data_observer);
 
   return pdm->GetProfiles();
 }
@@ -377,15 +404,37 @@
 }
 
 bool AutofillProfileChecker::Wait() {
-  autofill_helper::GetPersonalDataManager(profile_a_)->Refresh();
-  autofill_helper::GetPersonalDataManager(profile_b_)->Refresh();
+  PersonalDataLoadedObserverMock personal_data_observer;
+  base::RunLoop run_loop_a;
+  base::RunLoop run_loop_b;
+  auto* pdm_a = autofill_helper::GetPersonalDataManager(profile_a_);
+  auto* pdm_b = autofill_helper::GetPersonalDataManager(profile_b_);
+  pdm_a->AddObserver(&personal_data_observer);
+  pdm_b->AddObserver(&personal_data_observer);
+
+  EXPECT_CALL(personal_data_observer, OnPersonalDataChanged())
+      .Times(testing::AnyNumber());
+
+  EXPECT_CALL(personal_data_observer, OnPersonalDataFinishedProfileTasks())
+      .WillRepeatedly(autofill_helper::QuitMessageLoop(&run_loop_a));
+  pdm_a->Refresh();
   // Similar to GetAllAutoFillProfiles() we need to make sure we are not reading
   // before any locally instigated async writes. This is run exactly one time
   // before the first IsExitConditionSatisfied() is called.
   WaitForCurrentTasksToComplete(
       GetWebDataService(profile_a_)->GetDBTaskRunner());
+  run_loop_a.Run();
+
+  EXPECT_CALL(personal_data_observer, OnPersonalDataFinishedProfileTasks())
+      .WillRepeatedly(autofill_helper::QuitMessageLoop(&run_loop_b));
+  pdm_b->Refresh();
   WaitForCurrentTasksToComplete(
       GetWebDataService(profile_b_)->GetDBTaskRunner());
+  run_loop_b.Run();
+
+  pdm_a->RemoveObserver(&personal_data_observer);
+  pdm_b->RemoveObserver(&personal_data_observer);
+
   return StatusChangeChecker::Wait();
 }
 
@@ -405,3 +454,6 @@
 void AutofillProfileChecker::OnPersonalDataChanged() {
   CheckExitCondition();
 }
+
+PersonalDataLoadedObserverMock::PersonalDataLoadedObserverMock() {}
+PersonalDataLoadedObserverMock::~PersonalDataLoadedObserverMock() {}
diff --git a/chrome/browser/sync/test/integration/autofill_helper.h b/chrome/browser/sync/test/integration/autofill_helper.h
index 00c99bd6..e9f1070 100644
--- a/chrome/browser/sync/test/integration/autofill_helper.h
+++ b/chrome/browser/sync/test/integration/autofill_helper.h
@@ -14,6 +14,7 @@
 #include "base/strings/string16.h"
 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
 #include "components/autofill/core/browser/personal_data_manager_observer.h"
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace autofill {
 class AutofillEntry;
@@ -137,4 +138,14 @@
   const int profile_b_;
 };
 
+class PersonalDataLoadedObserverMock
+    : public autofill::PersonalDataManagerObserver {
+ public:
+  PersonalDataLoadedObserverMock();
+  ~PersonalDataLoadedObserverMock() override;
+
+  MOCK_METHOD0(OnPersonalDataChanged, void());
+  MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void());
+};
+
 #endif  // CHROME_BROWSER_SYNC_TEST_INTEGRATION_AUTOFILL_HELPER_H_
diff --git a/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc b/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc
index f809691..e4f750d1 100644
--- a/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc
@@ -225,16 +225,13 @@
 
   // Add the same (but non-verified) profile on the other client, afterwards.
   AddProfile(0, profile0);
-  // This call avoids the standard de-duping mechanisms in PDM so there will be
-  // two profiles at client 0 for a while. In this sense, this test is not very
-  // realistic as this should not happen in reality. The test checks that
-  // autofill_profile sync is robust enough to handle this situation.
-  EXPECT_EQ(2U, GetAllAutoFillProfiles(0).size());
   EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait());
 
-  // The profiles should de-duplicate via sync on the other client, the verified
-  // one should win.
+  // The profiles should de-duplicate via sync on both other client, the
+  // verified one should win.
   EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
+  EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
+
   EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
   EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
 }
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 2cdcea7..865c90a 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -75,6 +75,7 @@
   ~PersonalDataLoadedObserverMock() override {}
 
   MOCK_METHOD0(OnPersonalDataChanged, void());
+  MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void());
 };
 
 template <typename T>
@@ -128,10 +129,7 @@
     personal_data_manager_->AddObserver(&personal_data_observer_);
     personal_data_manager_->OnSyncServiceInitialized(nullptr);
 
-    base::RunLoop run_loop;
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillOnce(QuitMessageLoop(&run_loop));
-    run_loop.Run();
+    WaitForOnPersonalDataChanged();
   }
 
   void EnableWalletCardImport() {
@@ -196,11 +194,7 @@
     personal_data_manager_->OnAcceptedLocalCreditCardSave(
         *imported_credit_card);
 
-    base::RunLoop run_loop;
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillOnce(QuitMessageLoop(&run_loop));
-    run_loop.Run();
-
+    WaitForOnPersonalDataChanged();
     CreditCard expected(base::GenerateGUID(), test::kEmptyOrigin);
     test::SetCreditCardInfo(&expected, exp_name, exp_cc_num, exp_cc_month,
                             exp_cc_year, "");
@@ -212,8 +206,10 @@
 
   void WaitForOnPersonalDataChanged() {
     base::RunLoop run_loop;
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
         .WillOnce(QuitMessageLoop(&run_loop));
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+        .Times(testing::AnyNumber());
     run_loop.Run();
   }
 
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 409bb94..a4cbe059 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -305,6 +305,11 @@
   if (!database_helper_->GetLocalDatabase()) {
     return;
   }
+
+  database_helper_->GetLocalDatabase()->SetAutofillProfileChangedCallback(
+      base::BindRepeating(&PersonalDataManager::OnAutofillProfileChanged,
+                          weak_factory_.GetWeakPtr()));
+
   LoadProfiles();
   LoadCreditCards();
   LoadPaymentsCustomerData();
@@ -629,14 +634,13 @@
     profile->RecordAndLogUse();
 
     if (profile->record_type() == AutofillProfile::LOCAL_PROFILE) {
-      database_helper_->GetLocalDatabase()->UpdateAutofillProfile(*profile);
+      UpdateProfileInDB(*profile);
     } else if (profile->record_type() == AutofillProfile::SERVER_PROFILE) {
       // TODO(crbug.com/864519): Update this once addresses support account
       // storage, and also use the server database.
       database_helper_->GetLocalDatabase()->UpdateServerAddressMetadata(
           *profile);
     }
-
     Refresh();
   }
 }
@@ -648,39 +652,16 @@
   if (is_off_the_record_)
     return;
 
-  if (profile.IsEmpty(app_locale_))
-    return;
-
-  // Don't add an existing profile.
-  if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()))
-    return;
-
   if (!database_helper_->GetLocalDatabase())
     return;
 
-  // Don't add a duplicate.
-  if (FindByContents(web_profiles_, profile))
-    return;
-
-  // Add the new profile to the web database.
-  database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
-
-  // Refresh our local cache and send notifications to observers.
-  Refresh();
+  AddProfileToDB(profile);
 }
 
 void PersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
   if (is_off_the_record_)
     return;
 
-  AutofillProfile* existing_profile = GetProfileByGUID(profile.guid());
-  if (!existing_profile)
-    return;
-
-  // Don't overwrite the origin for a profile that is already stored.
-  if (existing_profile->EqualsSansOrigin(profile))
-    return;
-
   if (profile.IsEmpty(app_locale_)) {
     RemoveByGUID(profile.guid());
     return;
@@ -689,11 +670,7 @@
   if (!database_helper_->GetLocalDatabase())
     return;
 
-  // Make the update.
-  database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
-
-  // Refresh our local cache and send notifications to observers.
-  Refresh();
+  UpdateProfileInDB(profile);
 }
 
 AutofillProfile* PersonalDataManager::GetProfileByGUID(
@@ -927,9 +904,9 @@
 }
 
 void PersonalDataManager::
-    RemoveAutofillProfileByGUIDAndBlankCreditCardReferecne(
+    RemoveAutofillProfileByGUIDAndBlankCreditCardReference(
         const std::string& guid) {
-  database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
+  RemoveProfileFromDB(guid);
 
   // Reset the billing_address_id of any card that refered to this profile.
   for (CreditCard* credit_card : GetCreditCards()) {
@@ -952,23 +929,17 @@
   if (is_off_the_record_)
     return;
 
-  bool is_credit_card = FindByGUID<CreditCard>(local_credit_cards_, guid);
-  bool is_profile =
-      !is_credit_card && FindByGUID<AutofillProfile>(web_profiles_, guid);
-  if (!is_credit_card && !is_profile)
-    return;
-
   if (!database_helper_->GetLocalDatabase())
     return;
 
+  bool is_credit_card = FindByGUID<CreditCard>(local_credit_cards_, guid);
   if (is_credit_card) {
     database_helper_->GetLocalDatabase()->RemoveCreditCard(guid);
+    // Refresh our local cache and send notifications to observers.
+    Refresh();
   } else {
-    RemoveAutofillProfileByGUIDAndBlankCreditCardReferecne(guid);
+    RemoveAutofillProfileByGUIDAndBlankCreditCardReference(guid);
   }
-
-  // Refresh our local cache and send notifications to observers.
-  Refresh();
 }
 
 CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) {
@@ -1011,9 +982,9 @@
 
 void PersonalDataManager::UpdateProfilesServerValidityMapsIfNeeded(
     const std::vector<AutofillProfile*>& profiles) {
-  if (!profiles_server_validities_need_update)
+  if (!profiles_server_validities_need_update_)
     return;
-  profiles_server_validities_need_update = false;
+  profiles_server_validities_need_update_ = false;
   for (auto* profile : profiles) {
     profile->UpdateServerValidityMap(GetProfileValidityByGUID(profile->guid()));
   }
@@ -1092,7 +1063,6 @@
   LoadProfiles();
   LoadCreditCards();
   LoadPaymentsCustomerData();
-  profiles_server_validities_need_update = true;
 }
 
 std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest()
@@ -1363,20 +1333,13 @@
 }
 
 void PersonalDataManager::ClearProfileNonSettingsOrigins() {
-  bool has_updated = false;
-
   for (AutofillProfile* profile : GetProfiles()) {
     if (profile->origin() != kSettingsOrigin && !profile->origin().empty()) {
       profile->set_origin(std::string());
-      database_helper_->GetLocalDatabase()->UpdateAutofillProfile(*profile);
-      has_updated = true;
+      UpdateProfileInDB(*profile);
     }
   }
 
-  // Refresh the local cache and send notifications to observers if a changed
-  // was made.
-  if (has_updated)
-    Refresh();
 }
 
 void PersonalDataManager::ClearCreditCardNonSettingsOrigins() {
@@ -1404,7 +1367,6 @@
   if (pref_service_->GetBoolean(prefs::kAutofillJapanCityFieldMigrated))
     return;
 
-  bool has_updated = false;
   base::string16 japan_country_code = base::ASCIIToUTF16("JP");
   base::string16 line_separator = base::ASCIIToUTF16("\n");
   for (AutofillProfile* profile : GetProfiles()) {
@@ -1420,16 +1382,10 @@
       profile->SetRawInfo(ADDRESS_HOME_CITY, base::string16());
 
       // Make the update.
-      database_helper_->GetLocalDatabase()->UpdateAutofillProfile(*profile);
-      has_updated = true;
+      UpdateProfileInDB(*profile);
     }
   }
 
-  // Refresh the local cache and send notifications to observers if a change was
-  // made.
-  if (has_updated)
-    Refresh();
-
   // Set the pref so that this migration is never run again.
   pref_service_->SetBoolean(prefs::kAutofillJapanCityFieldMigrated, true);
 }
@@ -1452,7 +1408,7 @@
     const std::string& guid) {
   static const ProfileValidityMap& empty_validity_map = ProfileValidityMap();
   if (!synced_profile_validity_) {
-    profiles_server_validities_need_update = true;
+    profiles_server_validities_need_update_ = true;
     synced_profile_validity_ = std::make_unique<UserProfileValidityMap>();
     if (!synced_profile_validity_->ParseFromString(
             ::autofill::prefs::GetAllProfilesValidityMapsEncodedString(
@@ -1605,31 +1561,25 @@
 void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
   if (is_off_the_record_)
     return;
-
-  // Remove empty profiles from input.
-  base::EraseIf(*profiles, IsEmptyFunctor<AutofillProfile>(app_locale_));
-
   if (!database_helper_->GetLocalDatabase())
     return;
 
+  ClearOnGoingProfileChanges();
+
   // Any profiles that are not in the new profile list should be removed from
-  // the web database.
+  // the web database
   for (const auto& it : web_profiles_) {
     if (!FindByGUID<AutofillProfile>(*profiles, it->guid()))
-      database_helper_->GetLocalDatabase()->RemoveAutofillProfile(it->guid());
+      RemoveProfileFromDB(it->guid());
   }
 
-  // Update the web database with the existing profiles.
+  // Update the web database with the new and existing profiles.
   for (const AutofillProfile& it : *profiles) {
-    if (FindByGUID<AutofillProfile>(web_profiles_, it.guid()))
-      database_helper_->GetLocalDatabase()->UpdateAutofillProfile(it);
-  }
-
-  // Add the new profiles to the web database.  Don't add a duplicate.
-  for (const AutofillProfile& it : *profiles) {
-    if (!FindByGUID<AutofillProfile>(web_profiles_, it.guid()) &&
-        !FindByContents(web_profiles_, it))
-      database_helper_->GetLocalDatabase()->AddAutofillProfile(it);
+    if (FindByGUID<AutofillProfile>(web_profiles_, it.guid())) {
+      UpdateProfileInDB(it);
+    } else {
+      AddProfileToDB(it);
+    }
   }
 
   // Copy in the new profiles.
@@ -1637,9 +1587,6 @@
   for (const AutofillProfile& it : *profiles) {
     web_profiles_.push_back(std::make_unique<AutofillProfile>(it));
   }
-
-  // Refresh our local cache and send notifications to observers.
-  Refresh();
 }
 
 void PersonalDataManager::SetCreditCards(
@@ -1775,8 +1722,13 @@
 }
 
 void PersonalDataManager::NotifyPersonalDataChanged() {
-  for (PersonalDataManagerObserver& observer : observers_)
+  bool profile_changes_are_on_going = ProfileChangesAreOnGoing();
+  for (PersonalDataManagerObserver& observer : observers_) {
     observer.OnPersonalDataChanged();
+    if (!profile_changes_are_on_going) {
+      observer.OnPersonalDataFinishedProfileTasks();
+    }
+  }
 
   // If new data was synced, try to convert new server profiles and update
   // server cards.
@@ -1992,6 +1944,53 @@
       /*opted_in=*/true);
 }
 
+void PersonalDataManager::OnAutofillProfileChanged(
+    const AutofillProfileDeepChange& change) {
+  const auto& guid = change.key();
+  const auto& change_type = change.type();
+  const auto& profile = change.profile();
+
+  DCHECK(guid == profile.guid());
+
+  // Happens only in tests.
+  if (!ProfileChangesAreOnGoing(guid)) {
+    DVLOG(1) << "Received an unexpected response from database.";
+    return;
+  }
+
+  const auto* existing_profile = GetProfileByGUID(guid);
+  const bool profile_exists = (existing_profile != nullptr);
+  switch (change_type) {
+    case AutofillProfileChange::ADD:
+      profiles_server_validities_need_update_ = true;
+      if (!profile_exists && !FindByContents(web_profiles_, profile)) {
+        web_profiles_.push_back(std::make_unique<AutofillProfile>(profile));
+      }
+      break;
+    case AutofillProfileChange::UPDATE:
+      profiles_server_validities_need_update_ = true;
+      if (profile_exists && !existing_profile->EqualsSansOrigin(profile)) {
+        web_profiles_.erase(
+            FindElementByGUID<AutofillProfile>(web_profiles_, guid));
+        web_profiles_.push_back(std::make_unique<AutofillProfile>(profile));
+      }
+      break;
+    case AutofillProfileChange::REMOVE:
+      if (profile_exists) {
+        web_profiles_.erase(
+            FindElementByGUID<AutofillProfile>(web_profiles_, guid));
+      }
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  ongoing_profile_changes_[guid].pop();
+
+  NotifyPersonalDataChanged();
+  HandleNextProfileChange(guid);
+}
+
 void PersonalDataManager::LogServerCardLinkClicked() const {
   AutofillMetrics::LogServerCardLinkClicked(GetSyncSigninState());
 }
@@ -2132,11 +2131,10 @@
   for (const auto& profile : web_profiles_) {
     // If the profile was set to be deleted, remove it from the database.
     if (profiles_to_delete.count(profile.get())) {
-      database_helper_->GetLocalDatabase()->RemoveAutofillProfile(
-          profile->guid());
+      RemoveProfileFromDB(profile->guid());
     } else {
       // Otherwise, update the profile in the database.
-      database_helper_->GetLocalDatabase()->UpdateAutofillProfile(*profile);
+      UpdateProfileInDB(*profile);
     }
   }
 
@@ -2145,10 +2143,6 @@
   // Set the pref to the current major version.
   pref_service_->SetInteger(prefs::kAutofillLastVersionDeduped,
                             current_major_version);
-
-  // Refresh the local cache and send notifications to observers.
-  Refresh();
-
   return true;
 }
 
@@ -2278,6 +2272,7 @@
             *credit_card);
     }
   }
+  Refresh();
 }
 
 void PersonalDataManager::ConvertWalletAddressesAndUpdateWalletCards() {
@@ -2318,7 +2313,6 @@
     // TODO(crbug.com/915229): Remove once the investigation is over.
     if (has_converted_addresses)
       DLOG(WARNING) << this << " conversion of addresses done";
-    Refresh();
   }
 }
 
@@ -2523,7 +2517,7 @@
   size_t num_deleted_addresses = guids_to_delete.size();
 
   for (auto const guid : guids_to_delete) {
-    RemoveAutofillProfileByGUIDAndBlankCreditCardReferecne(guid);
+    RemoveAutofillProfileByGUIDAndBlankCreditCardReference(guid);
   }
 
   if (num_deleted_addresses > 0) {
@@ -2570,7 +2564,111 @@
 
 void PersonalDataManager::ResetProfileValidity() {
   synced_profile_validity_.reset();
-  profiles_server_validities_need_update = true;
+  profiles_server_validities_need_update_ = true;
+}
+
+void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile) {
+  // Add the new profile to the web database.
+  if (profile.IsEmpty(app_locale_)) {
+    NotifyPersonalDataChanged();
+    return;
+  }
+
+  if (!ProfileChangesAreOnGoing(profile.guid())) {
+    // Don't add an existing/empty profile.
+    if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()) ||
+        FindByContents(web_profiles_, profile)) {
+      NotifyPersonalDataChanged();
+      return;
+    }
+    database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
+  }
+
+  ongoing_profile_changes_[profile.guid()].push(
+      AutofillProfileDeepChange(AutofillProfileChange::ADD, profile));
+}
+
+void PersonalDataManager::UpdateProfileInDB(const AutofillProfile& profile) {
+  // Update the profile in the web database.
+  if (!ProfileChangesAreOnGoing(profile.guid())) {
+    database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
+  }
+  ongoing_profile_changes_[profile.guid()].push(
+      AutofillProfileDeepChange(AutofillProfileChange::UPDATE, profile));
+}
+
+void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
+  bool profile_exists = FindByGUID<AutofillProfile>(web_profiles_, guid);
+  if (!profile_exists && !ProfileChangesAreOnGoing(guid)) {
+    NotifyPersonalDataChanged();
+    return;
+  }
+
+  if (!ProfileChangesAreOnGoing(guid))
+    database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
+  ongoing_profile_changes_[guid].push(
+      AutofillProfileDeepChange(AutofillProfileChange::REMOVE, guid));
+}
+
+void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
+  if (!ProfileChangesAreOnGoing(guid))
+    return;
+
+  const auto& change_type = ongoing_profile_changes_[guid].front().type();
+  const auto* existing_profile = GetProfileByGUID(guid);
+  const bool profile_exists = (existing_profile != nullptr);
+  const auto& profile = ongoing_profile_changes_[guid].front().profile();
+
+  DCHECK(guid == profile.guid());
+
+  if (change_type == AutofillProfileChange::REMOVE) {
+    if (!profile_exists) {
+      ongoing_profile_changes_[guid].pop();
+      NotifyPersonalDataChanged();
+      HandleNextProfileChange(guid);
+      return;
+    }
+    database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
+    return;
+  }
+
+  if (change_type == AutofillProfileChange::ADD) {
+    if (profile_exists || FindByContents(web_profiles_, profile)) {
+      ongoing_profile_changes_[guid].pop();
+      NotifyPersonalDataChanged();
+      HandleNextProfileChange(guid);
+      return;
+    }
+    database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
+    return;
+  }
+
+  if (!profile_exists || existing_profile->EqualsSansOrigin(profile)) {
+    ongoing_profile_changes_[guid].pop();
+    NotifyPersonalDataChanged();
+    HandleNextProfileChange(guid);
+    return;
+  }
+  database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
+}
+
+bool PersonalDataManager::ProfileChangesAreOnGoing(const std::string& guid) {
+  return ongoing_profile_changes_.find(guid) !=
+             ongoing_profile_changes_.end() &&
+         !ongoing_profile_changes_[guid].empty();
+}
+
+bool PersonalDataManager::ProfileChangesAreOnGoing() {
+  for (auto task : ongoing_profile_changes_) {
+    if (ProfileChangesAreOnGoing(task.first)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void PersonalDataManager::ClearOnGoingProfileChanges() {
+  ongoing_profile_changes_.clear();
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index f8bd2d11..8e0c4dc 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -28,6 +28,7 @@
 #include "components/autofill/core/browser/suggestion.h"
 #include "components/autofill/core/browser/sync_utils.h"
 #include "components/autofill/core/browser/test_data_creator.h"
+#include "components/autofill/core/browser/webdata/autofill_change.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
 #include "components/history/core/browser/history_service_observer.h"
@@ -395,6 +396,9 @@
   // Records the sync transport consent if the user is in sync transport mode.
   virtual void OnUserAcceptedUpstreamOffer();
 
+  // Triggered when a profile is added/updated/removed on db.
+  void OnAutofillProfileChanged(const AutofillProfileDeepChange& change);
+
  protected:
   // Only PersonalDataManagerFactory and certain tests can create instances of
   // PersonalDataManager.
@@ -498,15 +502,9 @@
                               std::vector<AutofillProfile>* profiles);
 
   // Sets |web_profiles_| to the contents of |profiles| and updates the web
-  // database by adding, updating and removing profiles.
-  // The relationship between this and Refresh is subtle.
-  // A call to |SetProfiles| could include out-of-date data that may conflict
-  // if we didn't refresh-to-latest before an Autofill window was opened for
-  // editing. |SetProfiles| is implemented to make a "best effort" to apply the
-  // changes, but in extremely rare edge cases it is possible not all of the
-  // updates in |profiles| make it to the DB.  This is why SetProfiles will
-  // invoke Refresh after finishing, to ensure we get into a
-  // consistent state.  See Refresh for details.
+  // database by adding, updating and removing profiles. |web_profiles_| need to
+  // be updated at the end of the function, since some tasks cannot tolerate
+  // database delays.
   virtual void SetProfiles(std::vector<AutofillProfile>* profiles);
 
   // Sets |credit_cards_| to the contents of |credit_cards| and updates the web
@@ -618,7 +616,7 @@
   base::ObserverList<PersonalDataManagerObserver>::Unchecked observers_;
 
   // |profile_valditiies_need_update| whenever the profile validities are out of
-  bool profiles_server_validities_need_update = true;
+  bool profiles_server_validities_need_update_ = true;
 
  private:
   // Saves |imported_credit_card| to the WebDB if it exists. Returns the guid of
@@ -716,7 +714,7 @@
   // card's billing address if that address is used by any credit cards.
   // The method does not refresh, this allows multiple removal with one
   // refreshing in the end.
-  void RemoveAutofillProfileByGUIDAndBlankCreditCardReferecne(
+  void RemoveAutofillProfileByGUIDAndBlankCreditCardReference(
       const std::string& guid);
 
   // Returns true if an address can be deleted in a major version upgrade.
@@ -735,6 +733,22 @@
   // Resets |synced_profile_validity_|.
   void ResetProfileValidity();
 
+  // Add/Update/Remove profiles on DB.
+  void AddProfileToDB(const AutofillProfile& profile);
+  void UpdateProfileInDB(const AutofillProfile& profile);
+  void RemoveProfileFromDB(const std::string& guid);
+
+  // Look at the next profile change for profile with guid = |guid|, and handle
+  // it.
+  void HandleNextProfileChange(const std::string& guid);
+  // returns true if there is any profile change that's still on going.
+  bool ProfileChangesAreOnGoing();
+  // returns true if there is any ongoing change for profile with guid = |guid|
+  // that's still on going.
+  bool ProfileChangesAreOnGoing(const std::string& guid);
+  // Clear |ongoing_profile_changes_|.
+  void ClearOnGoingProfileChanges();
+
   const std::string app_locale_;
 
   // The default country code for new addresses.
@@ -761,6 +775,10 @@
   // |profile_validities_need_update| whenever this is changed.
   std::unique_ptr<UserProfileValidityMap> synced_profile_validity_;
 
+  // A timely ordered list of on going changes for each profile.
+  std::unordered_map<std::string, std::queue<AutofillProfileDeepChange>>
+      ongoing_profile_changes_;
+
   // The client side profile validator.
   AutofillProfileValidator* client_profile_validator_ = nullptr;
 
diff --git a/components/autofill/core/browser/personal_data_manager_observer.h b/components/autofill/core/browser/personal_data_manager_observer.h
index e948d3f..d09bc93 100644
--- a/components/autofill/core/browser/personal_data_manager_observer.h
+++ b/components/autofill/core/browser/personal_data_manager_observer.h
@@ -18,6 +18,10 @@
   // Called when there is insufficient data to fill a form. Used for testing.
   virtual void OnInsufficientFormData() {}
 
+  // Notifies the observer that the PersonalDataManager has no more tasks to
+  // handle.
+  virtual void OnPersonalDataFinishedProfileTasks() {}
+
  protected:
   virtual ~PersonalDataManagerObserver() {}
 };
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index bfc241d2..b6a4276 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -72,8 +72,8 @@
 const base::Time kSomeLaterTime = base::Time::FromDoubleT(1000);
 const base::Time kMuchLaterTime = base::Time::FromDoubleT(5000);
 
-ACTION(QuitMainMessageLoop) {
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+ACTION_P(QuitMessageLoop, loop) {
+  loop->Quit();
 }
 
 class PersonalDataLoadedObserverMock : public PersonalDataManagerObserver {
@@ -82,6 +82,7 @@
   ~PersonalDataLoadedObserverMock() override {}
 
   MOCK_METHOD0(OnPersonalDataChanged, void());
+  MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void());
 };
 
 class PersonalDataManagerMock : public PersonalDataManager {
@@ -193,6 +194,7 @@
   void ResetPersonalDataManager(UserMode user_mode,
                                 bool use_sync_transport_mode) {
     bool is_incognito = (user_mode == USER_MODE_INCOGNITO);
+
     personal_data_.reset(new PersonalDataManagerMock("en"));
     personal_data_->Init(
         scoped_refptr<AutofillWebDataService>(profile_database_service_),
@@ -213,10 +215,7 @@
     personal_data_->OnSyncServiceInitialized(&sync_service_);
     personal_data_->OnStateChanged(&sync_service_);
 
-    // Verify that the web database has been updated and the notification sent.
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillRepeatedly(QuitMainMessageLoop());
-    base::RunLoop().Run();
+    WaitForOnPersonalDataChanged();
   }
 
   void ResetPersonalDataManager(UserMode user_mode) {
@@ -226,6 +225,7 @@
   void ResetProfiles() {
     std::vector<AutofillProfile> empty_profiles;
     personal_data_->SetProfiles(&empty_profiles);
+    WaitForOnPersonalDataChanged();
   }
 
   bool TurnOnSyncFeature() WARN_UNUSED_RESULT {
@@ -253,11 +253,7 @@
     test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
                          "johnwayne@me.xyz", "Fox", "123 Zoo St", "unit 5",
                          "Hollywood", "CA", "91601", "US", "12345678910");
-    personal_data_->AddProfile(profile);
-
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillOnce(QuitMainMessageLoop());
-    base::RunLoop().Run();
+    AddProfileToPersonalDataManager(profile);
 
     ASSERT_EQ(1U, personal_data_->GetProfiles().size());
   }
@@ -298,10 +294,7 @@
                             "1");
     personal_data_->AddCreditCard(credit_card2);
 
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillOnce(QuitMainMessageLoop());
-    base::RunLoop().Run();
-
+    WaitOnceForOnPersonalDataChanged();
     ASSERT_EQ(3U, personal_data_->GetCreditCards().size());
   }
 
@@ -318,9 +311,7 @@
     masked_server_card.set_server_id("masked_id");
     masked_server_card.set_use_count(15);
     personal_data_->AddFullServerCreditCard(masked_server_card);
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillOnce(QuitMainMessageLoop());
-    base::RunLoop().Run();
+    WaitOnceForOnPersonalDataChanged();
     ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
 
 // Cards are automatically remasked on Linux since full server cards are not
@@ -349,10 +340,7 @@
     local_card.set_use_count(5);
     personal_data_->AddCreditCard(local_card);
 
-    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillOnce(QuitMainMessageLoop());
-    base::RunLoop().Run();
-
+    WaitOnceForOnPersonalDataChanged();
     EXPECT_EQ(3U, personal_data_->GetCreditCards().size());
   }
 
@@ -379,9 +367,8 @@
     AutofillProfile profile0(test::GetFullProfile());
     profile0.set_use_date(AutofillClock::Now() -
                           base::TimeDelta::FromDays(400));
-    personal_data_->AddProfile(profile0);
+    AddProfileToPersonalDataManager(profile0);
 
-    WaitForOnPersonalDataChanged();
     EXPECT_EQ(1U, personal_data_->GetProfiles().size());
   }
 
@@ -390,6 +377,38 @@
                                                   : account_autofill_table_;
   }
 
+  void AddProfileToPersonalDataManager(const AutofillProfile& profile) {
+    base::RunLoop run_loop;
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillOnce(QuitMessageLoop(&run_loop));
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+        .Times(testing::AnyNumber());
+    personal_data_->AddProfile(profile);
+    run_loop.Run();
+  }
+
+  void UpdateProfileOnPersonalDataManager(const AutofillProfile& profile) {
+    base::RunLoop run_loop;
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillOnce(QuitMessageLoop(&run_loop));
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+        .Times(testing::AnyNumber());
+
+    personal_data_->UpdateProfile(profile);
+    run_loop.Run();
+  }
+
+  void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
+    base::RunLoop run_loop;
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillOnce(QuitMessageLoop(&run_loop));
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+        .Times(testing::AnyNumber());
+
+    personal_data_->RemoveByGUID(guid);
+    run_loop.Run();
+  }
+
   void SetServerCards(const std::vector<CreditCard>& server_cards) {
     test::SetServerCreditCards(GetServerDataTable(), server_cards);
   }
@@ -400,9 +419,20 @@
 
   // Verifies that the web database has been updated and the notification sent.
   void WaitForOnPersonalDataChanged() {
+    base::RunLoop run_loop;
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillOnce(QuitMessageLoop(&run_loop));
     EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-        .WillRepeatedly(QuitMainMessageLoop());
-    base::RunLoop().Run();
+        .Times(testing::AnyNumber());
+    run_loop.Run();
+  }
+
+  void WaitOnceForOnPersonalDataChanged() {
+    base::RunLoop run_loop;
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillOnce(QuitMessageLoop(&run_loop));
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+    run_loop.Run();
   }
 
   void ExpectOnValidated(AutofillProfile* profile) {
@@ -462,11 +492,9 @@
   // Add profile0 to the database.
   AutofillProfile profile0(test::GetFullProfile());
   profile0.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("j@s.com"));
-  personal_data_->AddProfile(profile0);
-
+  AddProfileToPersonalDataManager(profile0);
   // Reload the database.
   ResetPersonalDataManager(USER_MODE_NORMAL);
-
   // Verify the addition.
   const std::vector<AutofillProfile*>& results1 = personal_data_->GetProfiles();
   ASSERT_EQ(1U, results1.size());
@@ -475,7 +503,8 @@
   // Add profile with identical values.  Duplicates should not get saved.
   AutofillProfile profile0a = profile0;
   profile0a.set_guid(base::GenerateGUID());
-  personal_data_->AddProfile(profile0a);
+
+  AddProfileToPersonalDataManager(profile0a);
 
   // Reload the database.
   ResetPersonalDataManager(USER_MODE_NORMAL);
@@ -493,7 +522,7 @@
   // Add the different profile.  This should save as a separate profile.
   // Note that if this same profile was "merged" it would collapse to one
   // profile with a multi-valued entry for email.
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   // Reload the database.
   ResetPersonalDataManager(USER_MODE_NORMAL);
@@ -505,17 +534,44 @@
   ExpectSameElements(profiles, personal_data_->GetProfiles());
 }
 
-// TODO(crbug.com/909730): If you add a profile and then remove it right away,
-// the profile will not be removed, but it should.
-TEST_F(PersonalDataManagerTest, AddRemoveProfile) {
+// Adding, updating, removing operations without waiting in between.
+TEST_F(PersonalDataManagerTest, AddRemoveUpdateProfileSequence) {
   AutofillProfile profile(test::GetFullProfile());
 
   personal_data_->AddProfile(profile);
   personal_data_->RemoveByGUID(profile.guid());
-
   WaitForOnPersonalDataChanged();
+
   auto profiles = personal_data_->GetProfiles();
-  ASSERT_EQ(1U, profiles.size());  // the correct size is 0.
+  ASSERT_EQ(0U, profiles.size());
+
+  personal_data_->AddProfile(profile);
+  personal_data_->RemoveByGUID(profile.guid());
+  personal_data_->RemoveByGUID(profile.guid());
+  WaitForOnPersonalDataChanged();
+  profiles = personal_data_->GetProfiles();
+  ASSERT_EQ(0U, profiles.size());
+
+  personal_data_->AddProfile(profile);
+  profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
+  personal_data_->UpdateProfile(profile);
+  WaitForOnPersonalDataChanged();
+
+  profiles = personal_data_->GetProfiles();
+  ASSERT_EQ(1U, profiles.size());
+  EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
+            base::ASCIIToUTF16("new@email.com"));
+
+  profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
+  personal_data_->UpdateProfile(profile);
+  profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newer@email.com"));
+  personal_data_->UpdateProfile(profile);
+  WaitForOnPersonalDataChanged();
+
+  profiles = personal_data_->GetProfiles();
+  ASSERT_EQ(1U, profiles.size());
+  EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
+            base::ASCIIToUTF16("newer@email.com"));
 }
 
 // Test that a new profile has its basic information set.
@@ -527,7 +583,7 @@
   // Add a profile to the database.
   AutofillProfile profile(test::GetFullProfile());
   profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("j@s.com"));
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
 
   // Reload the database.
   ResetPersonalDataManager(USER_MODE_NORMAL);
@@ -686,7 +742,7 @@
   std::vector<AutofillProfile> profiles;
   profiles.push_back(with_invalid);
   personal_data_->SetProfiles(&profiles);
-
+  WaitForOnPersonalDataChanged();
   ASSERT_EQ(1u, personal_data_->GetProfiles().size());
   AutofillProfile profile = *personal_data_->GetProfiles()[0];
   ASSERT_NE(without_invalid.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
@@ -699,6 +755,7 @@
   EXPECT_NE(base::Time(), profile.modification_date());
 
   personal_data_->SaveImportedProfile(profile);
+  WaitForOnPersonalDataChanged();
   const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
   ASSERT_EQ(1U, profiles.size());
   EXPECT_GT(base::TimeDelta::FromMilliseconds(500),
@@ -722,10 +779,8 @@
                        "Orlando", "FL", "32801", "US", "19482937549");
 
   // Add two test profiles to the database.
-  personal_data_->AddProfile(profile0);
-  personal_data_->AddProfile(profile1);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile0);
+  AddProfileToPersonalDataManager(profile1);
 
   std::vector<AutofillProfile*> profiles;
   profiles.push_back(&profile0);
@@ -734,11 +789,9 @@
 
   // Update, remove, and add.
   profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
-  personal_data_->UpdateProfile(profile0);
-  personal_data_->RemoveByGUID(profile1.guid());
-  personal_data_->AddProfile(profile2);
-
-  WaitForOnPersonalDataChanged();
+  UpdateProfileOnPersonalDataManager(profile0);
+  RemoveByGUIDFromPersonalDataManager(profile1.guid());
+  AddProfileToPersonalDataManager(profile2);
 
   profiles.clear();
   profiles.push_back(&profile0);
@@ -784,7 +837,7 @@
   // Update, remove, and add.
   credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Joe"));
   personal_data_->UpdateCreditCard(credit_card0);
-  personal_data_->RemoveByGUID(credit_card1.guid());
+  RemoveByGUIDFromPersonalDataManager(credit_card1.guid());
   personal_data_->AddCreditCard(credit_card2);
 
   WaitForOnPersonalDataChanged();
@@ -812,13 +865,8 @@
   credit_card3.set_record_type(CreditCard::FULL_SERVER_CARD);
   credit_card3.set_server_id("server_id");
 
-  // Verify that the web database has been updated and the notification sent.
-  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-      .WillOnce(QuitMainMessageLoop());
-
   personal_data_->AddFullServerCreditCard(credit_card3);
-
-  base::RunLoop().Run();
+  WaitForOnPersonalDataChanged();
 
   cards.push_back(&credit_card3);
   ExpectSameElements(cards, personal_data_->GetCreditCards());
@@ -957,7 +1005,7 @@
   EXPECT_FALSE(credit_card.IsVerified());
 
   // Add the data to the database.
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
   personal_data_->AddCreditCard(credit_card);
 
   WaitForOnPersonalDataChanged();
@@ -979,7 +1027,7 @@
   EXPECT_TRUE(profile.IsVerified());
   EXPECT_TRUE(credit_card.IsVerified());
 
-  personal_data_->UpdateProfile(profile);
+  UpdateProfileOnPersonalDataManager(profile);
   personal_data_->UpdateCreditCard(credit_card);
 
   // Note: No refresh, as no update is expected.
@@ -998,7 +1046,7 @@
   profile.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
   credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Joe"));
 
-  personal_data_->UpdateProfile(profile);
+  UpdateProfileOnPersonalDataManager(profile);
   personal_data_->UpdateCreditCard(credit_card);
 
   WaitForOnPersonalDataChanged();
@@ -1059,13 +1107,10 @@
                           "378282246310005" /* American Express */, "04",
                           "2999", "1");
 
-  // Verify that the web database has been updated and the notification sent.
-  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-      .WillOnce(QuitMainMessageLoop());
 
   personal_data_->AddFullServerCreditCard(server_card);
 
-  base::RunLoop().Run();
+  WaitForOnPersonalDataChanged();
 
   ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
   EXPECT_EQ(CreditCard::MASKED_SERVER_CARD,
@@ -1182,10 +1227,8 @@
                           "1");
 
   // Add two test profiles to the database.
-  personal_data_->AddProfile(profile0);
-  personal_data_->AddProfile(profile1);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile0);
+  AddProfileToPersonalDataManager(profile1);
 
   std::vector<AutofillProfile*> profiles;
   profiles.push_back(&profile0);
@@ -1221,9 +1264,7 @@
                        "");
 
   // Add the profile0 to the db.
-  personal_data_->AddProfile(profile0);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile0);
 
   // Verify that we've loaded the profiles from the web database.
   const std::vector<AutofillProfile*>& results2 = personal_data_->GetProfiles();
@@ -1234,9 +1275,7 @@
   AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile1, "z", "", "", "", "", "", "", "", "", "", "",
                        "");
-  personal_data_->AddProfile(profile1);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile1);
 
   // Make sure the two profiles have different GUIDs, both valid.
   const std::vector<AutofillProfile*>& results3 = personal_data_->GetProfiles();
@@ -1289,9 +1328,7 @@
                        "");
 
   // Add the empty profile to the database.
-  personal_data_->AddProfile(profile0);
-
-  // Note: no refresh here.
+  AddProfileToPersonalDataManager(profile0);
 
   // Reset the PersonalDataManager.  This tests that the personal data was saved
   // to the web database, and that we can load the profiles from the web
@@ -1332,10 +1369,8 @@
                        "Orlando", "FL", "32801", "US", "19482937549");
 
   // Add the test profiles to the database.
-  personal_data_->AddProfile(profile0);
-  personal_data_->AddProfile(profile1);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile0);
+  AddProfileToPersonalDataManager(profile1);
 
   std::vector<AutofillProfile*> profiles;
   profiles.push_back(&profile0);
@@ -1362,20 +1397,20 @@
   profile_database_service_->RemoveAutofillProfile(profile1.guid());
   profile_database_service_->RemoveAutofillProfile(profile2.guid());
 
-  // Before telling the PDM to refresh, simulate an edit to one of the deleted
-  // profiles via a SetProfile update (this would happen if the Autofill window
-  // was open with a previous snapshot of the profiles, and something
-  // [e.g. sync] removed a profile from the browser.  In this edge case, we will
-  // end up in a consistent state by dropping the write).
-  profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Mar"));
-  profile2.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Jo"));
-  personal_data_->UpdateProfile(profile0);
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-
+  personal_data_->Refresh();
   WaitForOnPersonalDataChanged();
 
-  const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
+  auto results = personal_data_->GetProfiles();
+  ASSERT_EQ(1U, results.size());
+  EXPECT_EQ(profile0, *results[0]);
+
+  profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Mar"));
+  profile_database_service_->UpdateAutofillProfile(profile0);
+
+  personal_data_->Refresh();
+  WaitForOnPersonalDataChanged();
+
+  results = personal_data_->GetProfiles();
   ASSERT_EQ(1U, results.size());
   EXPECT_EQ(profile0, *results[0]);
 }
@@ -1391,10 +1426,9 @@
   EXPECT_FALSE(profile.IsVerified());
 
   // Add the profile to the database.
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
 
   // Make sure everything is set up correctly.
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(1U, personal_data_->GetProfiles().size());
 
   AutofillProfile new_verified_profile = profile;
@@ -1465,10 +1499,9 @@
                        "johnwayne@me.xyz", nullptr, "123 Zoo St.", nullptr,
                        "Hollywood", "CA", "91601", "US", "14155678910");
 
-  personal_data_->AddProfile(profile0);
+  AddProfileToPersonalDataManager(profile0);
 
   // Make sure everything is set up correctly.
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(1U, personal_data_->GetProfiles().size());
 
   personal_data_->GetNonEmptyTypes(&non_empty_types);
@@ -1500,10 +1533,9 @@
                        "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
                        "Orlando", "FL", "32801", "US", "16502937549");
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
 
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(3U, personal_data_->GetProfiles().size());
 
   personal_data_->GetNonEmptyTypes(&non_empty_types);
@@ -1578,7 +1610,7 @@
   test::SetProfileInfo(&steve_jobs, "Steven", "Paul", "Jobs", "sjobs@apple.com",
                        "Apple Computer, Inc.", "1 Infinite Loop", "",
                        "Cupertino", "CA", "95014", "US", "(800) 275-2273");
-  personal_data_->AddProfile(steve_jobs);
+  AddProfileToPersonalDataManager(steve_jobs);
 
   CreditCard bill_gates(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetCreditCardInfo(&bill_gates, "William H. Gates", "5555555555554444",
@@ -1655,10 +1687,9 @@
   test::SetProfileInfo(&moose, "Moose", "P", "McMahon", "mpm@example.com", "",
                        "1 Taiga TKTR", "", "Calgary", "AB", "T2B 2K2", "CA",
                        "(800) 555-9000");
-  personal_data_->AddProfile(moose);
+  AddProfileToPersonalDataManager(moose);
 
   // Make sure everything is set up correctly.
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(1U, personal_data_->GetProfiles().size());
 
   // The value is cached and doesn't change even after adding an address.
@@ -1684,7 +1715,7 @@
   test::SetProfileInfo(&moose, "Moose", "P", "McMahon", "mpm@example.com", "",
                        "1 Taiga TKTR", "", "Calgary", "AB", "T2B 2K2", "CA",
                        "(800) 555-9000");
-  personal_data_->AddProfile(moose);
+  AddProfileToPersonalDataManager(moose);
   ResetPersonalDataManager(USER_MODE_NORMAL);
   EXPECT_EQ("CA", personal_data_->GetDefaultCountryCodeForNewAddress());
 
@@ -1697,38 +1728,27 @@
   test::SetProfileInfo(&armadillo2, "Armin", "Dill", "Oh", "ado@example.com",
                        "", "2 Speed Bump", "", "Lubbock", "TX", "77500", "MX",
                        "(800) 555-9000");
-  personal_data_->AddProfile(armadillo);
-  personal_data_->AddProfile(armadillo2);
+  AddProfileToPersonalDataManager(armadillo);
+  AddProfileToPersonalDataManager(armadillo2);
   ResetPersonalDataManager(USER_MODE_NORMAL);
   EXPECT_EQ("MX", personal_data_->GetDefaultCountryCodeForNewAddress());
 
-  personal_data_->RemoveByGUID(armadillo.guid());
-  personal_data_->RemoveByGUID(armadillo2.guid());
+  RemoveByGUIDFromPersonalDataManager(armadillo.guid());
+  RemoveByGUIDFromPersonalDataManager(armadillo2.guid());
   ResetPersonalDataManager(USER_MODE_NORMAL);
   // Verified profiles count more.
   armadillo.set_origin("http://randomwebsite.com");
   armadillo2.set_origin("http://randomwebsite.com");
-  personal_data_->AddProfile(armadillo);
-  personal_data_->AddProfile(armadillo2);
+  AddProfileToPersonalDataManager(armadillo);
+  AddProfileToPersonalDataManager(armadillo2);
   ResetPersonalDataManager(USER_MODE_NORMAL);
   EXPECT_EQ("CA", personal_data_->GetDefaultCountryCodeForNewAddress());
 
-  personal_data_->RemoveByGUID(armadillo.guid());
+  RemoveByGUIDFromPersonalDataManager(armadillo.guid());
   ResetPersonalDataManager(USER_MODE_NORMAL);
   // But unverified profiles can be a tie breaker.
   armadillo.set_origin(kSettingsOrigin);
-  personal_data_->AddProfile(armadillo);
-  ResetPersonalDataManager(USER_MODE_NORMAL);
-  EXPECT_EQ("MX", personal_data_->GetDefaultCountryCodeForNewAddress());
-
-  // Invalid country codes are ignored.
-  personal_data_->RemoveByGUID(armadillo.guid());
-  personal_data_->RemoveByGUID(moose.guid());
-  AutofillProfile space_invader(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(&space_invader, "Marty", "", "Martian", "mm@example.com",
-                       "", "1 Flying Object", "", "Valles Marineris", "", "",
-                       "XX", "");
-  personal_data_->AddProfile(moose);
+  AddProfileToPersonalDataManager(armadillo);
   ResetPersonalDataManager(USER_MODE_NORMAL);
   EXPECT_EQ("MX", personal_data_->GetDefaultCountryCodeForNewAddress());
 }
@@ -1738,17 +1758,14 @@
   test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
 
   // Make sure everything is set up correctly.
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(1U, personal_data_->GetProfiles().size());
   EXPECT_EQ(1U, personal_data_->GetProfiles().size());
 
   profile.set_language_code("en");
-  personal_data_->UpdateProfile(profile);
-
-  WaitForOnPersonalDataChanged();
+  UpdateProfileOnPersonalDataManager(profile);
 
   const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
   ASSERT_EQ(1U, results.size());
@@ -1762,7 +1779,7 @@
                        "johnwayne@me.xyz", "Fox",
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
   ResetPersonalDataManager(USER_MODE_NORMAL);
 
   std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
@@ -1779,7 +1796,7 @@
                        "johnwayne@me.xyz", "Fox",
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
   ResetPersonalDataManager(USER_MODE_NORMAL);
 
   std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
@@ -1813,10 +1830,10 @@
 
   // For easier results verification, make sure |profile| is suggested first.
   profile.set_use_count(5);
-  personal_data_->AddProfile(profile);
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-  personal_data_->AddProfile(profile3);
+  AddProfileToPersonalDataManager(profile);
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
   ResetPersonalDataManager(USER_MODE_NORMAL);
 
   // Simulate a form with street address, city and state.
@@ -1842,7 +1859,7 @@
                          "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox",
                          "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                          "Hollywood", "CA", "91601", "US", "12345678910");
-    personal_data_->AddProfile(profile);
+    AddProfileToPersonalDataManager(profile);
     profiles.push_back(profile);
   }
   ResetPersonalDataManager(USER_MODE_NORMAL);
@@ -1876,7 +1893,7 @@
     profile.set_use_count(12);
     profile.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
 
-    personal_data_->AddProfile(profile);
+    AddProfileToPersonalDataManager(profile);
     profiles.push_back(profile);
   }
 
@@ -1888,7 +1905,7 @@
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile.set_use_count(1);
   profile.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(7));
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
 
   ResetPersonalDataManager(USER_MODE_NORMAL);
 
@@ -1914,7 +1931,7 @@
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile3.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
   profile3.set_use_count(5);
-  personal_data_->AddProfile(profile3);
+  AddProfileToPersonalDataManager(profile3);
 
   AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
@@ -1923,7 +1940,7 @@
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
   profile1.set_use_count(10);
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
@@ -1932,7 +1949,7 @@
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(15));
   profile2.set_use_count(300);
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   ResetPersonalDataManager(USER_MODE_NORMAL);
   std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
@@ -1952,21 +1969,21 @@
                        "johnwayne@me.xyz", "Fox",
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox",
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile3, "Marion3", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox",
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile3);
+  AddProfileToPersonalDataManager(profile3);
 
   ResetPersonalDataManager(USER_MODE_NORMAL);
 
@@ -1988,7 +2005,7 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(200));
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
@@ -1996,7 +2013,7 @@
                        "456 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   ResetPersonalDataManager(USER_MODE_NORMAL);
 
@@ -2072,14 +2089,14 @@
   profile1.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
                             AutofillProfile::CLIENT);
   profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox",
                        "456 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "1234567890");
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   ResetPersonalDataManager(USER_MODE_NORMAL);
   {
@@ -2139,14 +2156,14 @@
                                              autofill_profile_validity);
   }
   profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox",
                        "456 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "NY", "91601", "US", "1234567890");
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   ResetPersonalDataManager(USER_MODE_NORMAL);
   {
@@ -2194,7 +2211,7 @@
   test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz",
                        "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
                        "Orlando", "FL", "32801", "US", "19482937549");
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Add a different server profile.
   std::vector<AutofillProfile> server_profiles;
@@ -2212,6 +2229,7 @@
   prefs::SetProfileAutofillEnabled(personal_data_->pref_service_, false);
   WaitForOnPersonalDataChanged();
   personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
+  WaitForOnPersonalDataChanged();
 
   // Check that profiles were saved.
   EXPECT_EQ(2U, personal_data_->GetProfiles().size());
@@ -2240,7 +2258,7 @@
   test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz",
                        "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
                        "Orlando", "FL", "32801", "US", "19482937549");
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Add a different server profile.
   std::vector<AutofillProfile> server_profiles;
@@ -2257,6 +2275,7 @@
   personal_data_->Refresh();
   WaitForOnPersonalDataChanged();
   personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
+  WaitForOnPersonalDataChanged();
 
   // Expect 2 autofilled values or suggestions.
   EXPECT_EQ(2U, personal_data_->GetProfiles().size());
@@ -2288,7 +2307,7 @@
   test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz",
                        "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
                        "Orlando", "FL", "32801", "US", "19482937549");
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Expect no profile values or suggestions were added.
   EXPECT_EQ(0U, personal_data_->GetProfiles().size());
@@ -3254,7 +3273,7 @@
   EXPECT_EQ(1U, profile.use_count());
   EXPECT_EQ(kArbitraryTime, profile.use_date());
   EXPECT_EQ(kArbitraryTime, profile.modification_date());
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
 
   CreditCard credit_card(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetCreditCardInfo(&credit_card, "John Dillinger",
@@ -3447,7 +3466,7 @@
 
 TEST_F(PersonalDataManagerTest, ClearAllLocalData) {
   // Add some local data.
-  personal_data_->AddProfile(test::GetFullProfile());
+  AddProfileToPersonalDataManager(test::GetFullProfile());
   personal_data_->AddCreditCard(test::GetCreditCard());
   personal_data_->Refresh();
 
@@ -3529,6 +3548,7 @@
   }
 
   personal_data_->SaveImportedProfile(profile2);
+  WaitForOnPersonalDataChanged();
 
   const std::vector<AutofillProfile*>& saved_profiles =
       personal_data_->GetProfiles();
@@ -4225,12 +4245,12 @@
   // Associate the third card with profile6.
   credit_card3.set_billing_address_id(profile6.guid());
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-  personal_data_->AddProfile(profile3);
-  personal_data_->AddProfile(profile4);
-  personal_data_->AddProfile(profile5);
-  personal_data_->AddProfile(profile6);
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
+  AddProfileToPersonalDataManager(profile4);
+  AddProfileToPersonalDataManager(profile5);
+  AddProfileToPersonalDataManager(profile6);
   personal_data_->AddCreditCard(credit_card1);
   personal_data_->AddCreditCard(credit_card2);
   personal_data_->AddCreditCard(credit_card3);
@@ -4304,11 +4324,9 @@
   profile3.set_use_count(3);
   profile3.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(5));
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-  personal_data_->AddProfile(profile3);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
 
   // Make sure the 3 profiles were saved;
   EXPECT_EQ(3U, personal_data_->GetProfiles().size());
@@ -4394,11 +4412,9 @@
   profile3.set_use_count(3);
   profile3.set_use_date(kArbitraryTime);
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-  personal_data_->AddProfile(profile3);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
 
   // Make sure the 3 profiles were saved.
   EXPECT_EQ(3U, personal_data_->GetProfiles().size());
@@ -4460,11 +4476,9 @@
   profile3.set_use_count(3);
   profile3.set_use_date(kArbitraryTime);
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-  personal_data_->AddProfile(profile3);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
 
   // Make sure the 3 profiles were saved.
   EXPECT_EQ(3U, personal_data_->GetProfiles().size());
@@ -4525,11 +4539,9 @@
   profile3.set_use_count(3);
   profile3.set_use_date(kArbitraryTime);
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-  personal_data_->AddProfile(profile3);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
 
   // Make sure the 3 profiles were saved.
   EXPECT_EQ(3U, personal_data_->GetProfiles().size());
@@ -4637,15 +4649,13 @@
   Barney.set_use_count(1);
   Barney.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(180));
 
-  personal_data_->AddProfile(Homer1);
-  personal_data_->AddProfile(Homer2);
-  personal_data_->AddProfile(Homer3);
-  personal_data_->AddProfile(Homer4);
-  personal_data_->AddProfile(Marge1);
-  personal_data_->AddProfile(Marge2);
-  personal_data_->AddProfile(Barney);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(Homer1);
+  AddProfileToPersonalDataManager(Homer2);
+  AddProfileToPersonalDataManager(Homer3);
+  AddProfileToPersonalDataManager(Homer4);
+  AddProfileToPersonalDataManager(Marge1);
+  AddProfileToPersonalDataManager(Marge2);
+  AddProfileToPersonalDataManager(Barney);
 
   // Make sure the 7 profiles were saved;
   EXPECT_EQ(7U, personal_data_->GetProfiles().size());
@@ -4728,10 +4738,8 @@
                        "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
                        "", "Springfield", "IL", "91601", "", "");
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
 
   // Make sure both profiles were saved.
   EXPECT_EQ(2U, personal_data_->GetProfiles().size());
@@ -4756,9 +4764,8 @@
                        "homer.simpson@abc.com", "", "742. Evergreen Terrace",
                        "", "Springfield", "IL", "91601", "US", "");
 
-  personal_data_->AddProfile(profile);
+  AddProfileToPersonalDataManager(profile);
 
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(1U, personal_data_->GetProfiles().size());
 
   // Enable the profile cleanup now. Otherwise it would be triggered by the
@@ -4782,10 +4789,9 @@
                        "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
                        "", "Springfield", "IL", "91601", "", "");
 
-  personal_data_->AddProfile(profile1);
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
 
-  WaitForOnPersonalDataChanged();
   EXPECT_EQ(2U, personal_data_->GetProfiles().size());
 
   // Enable the profile cleanup now. Otherwise it would be triggered by the
@@ -4807,8 +4813,7 @@
                        "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
                        "", "Springfield", "IL", "91601", "", "");
 
-  personal_data_->AddProfile(profile3);
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile3);
 
   // Make sure |profile3| was saved.
   EXPECT_EQ(2U, personal_data_->GetProfiles().size());
@@ -4857,7 +4862,7 @@
                        "1234 Evergreen Terrace", "Bld. 6", "Springfield", "IL",
                        "32801", "US", "15151231234");
   profile0.set_use_date(now - base::TimeDelta::FromDays(400));
-  personal_data_->AddProfile(profile0);
+  AddProfileToPersonalDataManager(profile0);
 
   // Create unverified/disused/used-by-expired-credit-card address(deletable).
   AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
@@ -4871,9 +4876,9 @@
                           "1");
   credit_card0.set_use_date(now - base::TimeDelta::FromDays(400));
   credit_card0.set_billing_address_id(profile1.guid());
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
   personal_data_->AddCreditCard(credit_card0);
-
+  WaitForOnPersonalDataChanged();
   // Create verified/disused/not-used-by-valid-credit-card address(not
   // deletable).
   AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
@@ -4882,7 +4887,7 @@
                        "32801", "US", "15151231234");
   profile2.set_origin(kSettingsOrigin);
   profile2.set_use_date(now - base::TimeDelta::FromDays(400));
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   // Create unverified/recently-used/not-used-by-valid-credit-card address(not
   // deletable).
@@ -4891,7 +4896,7 @@
                        "1234 Evergreen Terrace", "Bld. 9", "Springfield", "IL",
                        "32801", "US", "15151231234");
   profile3.set_use_date(now - base::TimeDelta::FromDays(4));
-  personal_data_->AddProfile(profile3);
+  AddProfileToPersonalDataManager(profile3);
 
   // Create unverified/disused/used-by-valid-credit-card address(not deletable).
   AutofillProfile profile4(base::GenerateGUID(), test::kEmptyOrigin);
@@ -4904,7 +4909,7 @@
   credit_card1.SetNetworkForMaskedCard(kVisaCard);
   credit_card1.set_billing_address_id(profile4.guid());
   credit_card1.set_use_date(now - base::TimeDelta::FromDays(1));
-  personal_data_->AddProfile(profile4);
+  AddProfileToPersonalDataManager(profile4);
   personal_data_->AddCreditCard(credit_card1);
 
   WaitForOnPersonalDataChanged();
@@ -5101,7 +5106,7 @@
                        "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
                        "Orlando", "FL", "32801", "US", "19482937549");
   local_profile.set_use_count(1);
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Add a different server profile.
   std::vector<AutofillProfile> server_profiles;
@@ -5207,7 +5212,7 @@
                        "1212 Center.", "Bld. 5", "Orlando", "FL", "32801", "US",
                        "19482937549");
   local_profile.set_use_count(1);
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Add a different server profile.
   std::vector<AutofillProfile> server_profiles;
@@ -5364,7 +5369,7 @@
                        "1212 Center.", "Bld. 5", "Orlando", "FL", "32801", "US",
                        "19482937549");
   local_profile.set_use_count(1);
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Add a server profile.
   std::vector<AutofillProfile> server_profiles;
@@ -5587,7 +5592,7 @@
   AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz", "",
                        "Fox", "1212 Center.", "Bld. 5", "", "", "", "", "");
-  personal_data_->AddProfile(local_profile);
+  AddProfileToPersonalDataManager(local_profile);
 
   // Add two server profiles: The first is unique, the second is similar to the
   // local one but has some additional info.
@@ -5680,8 +5685,8 @@
   server_cards.push_back(server_card1);
 
   // Add the data to the database.
-  personal_data_->AddProfile(profile0);
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile0);
+  AddProfileToPersonalDataManager(profile1);
   personal_data_->AddCreditCard(local_card0);
   personal_data_->AddCreditCard(local_card1);
   SetServerCards(server_cards);
@@ -5697,14 +5702,14 @@
   ///////////////////////////////////////////////////////////////////////
   // Tested method.
   ///////////////////////////////////////////////////////////////////////
-  personal_data_->RemoveByGUID(profile0.guid());
+  RemoveByGUIDFromPersonalDataManager(profile0.guid());
 
   ///////////////////////////////////////////////////////////////////////
   // Validation.
   ///////////////////////////////////////////////////////////////////////
 
   // Wait for the data to be refreshed.
-  WaitForOnPersonalDataChanged();
+  // WaitForOnPersonalDataChanged();
 
   // Make sure only profile0 was deleted.
   ASSERT_EQ(1U, personal_data_->GetProfiles().size());
@@ -5742,7 +5747,7 @@
   test::SetProfileInfo(&profile0, "Bob", "", "Doe", "", "Fox", "1212 Center.",
                        "Bld. 5", "Orlando", "FL", "32801", "US", "19482937549");
   profile0.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(3));
-  personal_data_->AddProfile(profile0);
+  AddProfileToPersonalDataManager(profile0);
 
   // Add a profile used a long time (200 days) ago.
   AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
@@ -5750,7 +5755,7 @@
                        "1234 Evergreen Terrace", "Bld. 5", "Springfield", "IL",
                        "32801", "US", "15151231234");
   profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(200));
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   // Reload the database, which will log the stored profile counts.
   base::HistogramTester histogram_tester;
@@ -6024,6 +6029,8 @@
 
   // Reloading the test profile should result in test data being created.
   ResetPersonalDataManager(USER_MODE_NORMAL);
+  WaitOnceForOnPersonalDataChanged();
+
   const std::vector<AutofillProfile*> addresses = personal_data_->GetProfiles();
   const std::vector<CreditCard*> credit_cards =
       personal_data_->GetCreditCards();
@@ -6359,7 +6366,7 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile0.set_use_count(10000);
-  personal_data_->AddProfile(profile0);
+  AddProfileToPersonalDataManager(profile0);
 
   AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
@@ -6367,7 +6374,7 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile1.set_use_count(1000);
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(base::GenerateGUID(), "1234");
   test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
@@ -6375,7 +6382,7 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile2.set_use_count(100);
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
   // Create a profile with a settings origin.
   AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
@@ -6384,9 +6391,8 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
   profile3.set_use_count(10);
-  personal_data_->AddProfile(profile3);
+  AddProfileToPersonalDataManager(profile3);
 
-  WaitForOnPersonalDataChanged();
   ASSERT_EQ(4U, personal_data_->GetProfiles().size());
 
   personal_data_->ClearProfileNonSettingsOrigins();
@@ -6466,7 +6472,7 @@
     test::SetProfileInfo(&profile0, "Homer", "J", "Simpson",
                          "homer.simpson@abc.com", "", "742. Evergreen Terrace",
                          "", "Springfield", "IL", "91601", "US", "");
-    personal_data_->AddProfile(profile0);
+    AddProfileToPersonalDataManager(profile0);
   }
 
   // A JP profile with both street address and a city.
@@ -6476,7 +6482,7 @@
     test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
                          "homer.simpson@abc.com", "", "742. Evergreen Terrace",
                          "", "Springfield", "IL", "91601", "JP", "");
-    personal_data_->AddProfile(profile1);
+    AddProfileToPersonalDataManager(profile1);
   }
 
   // A JP profile with only a city.
@@ -6486,7 +6492,7 @@
     test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
                          "homer.simpson@abc.com", "", "", "", "Springfield",
                          "IL", "91601", "JP", "");
-    personal_data_->AddProfile(profile2);
+    AddProfileToPersonalDataManager(profile2);
   }
 
   // A JP profile with only a street address.
@@ -6496,7 +6502,7 @@
     test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
                          "homer.simpson@abc.com", "", "742. Evergreen Terrace",
                          "", "", "IL", "91601", "JP", "");
-    personal_data_->AddProfile(profile3);
+    AddProfileToPersonalDataManager(profile3);
   }
 
   // A JP profile with neither a street address nor a city.
@@ -6506,11 +6512,9 @@
     test::SetProfileInfo(&profile4, "Homer", "J", "Simpson",
                          "homer.simpson@abc.com", "", "", "", "", "IL", "91601",
                          "JP", "");
-    personal_data_->AddProfile(profile4);
+    AddProfileToPersonalDataManager(profile4);
   }
 
-  WaitForOnPersonalDataChanged();
-
   personal_data_->MoveJapanCityToStreetAddress();
 
   WaitForOnPersonalDataChanged();
@@ -6566,8 +6570,7 @@
                        "johnwayne@me.xyz", "Fox",
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile);
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile);
 
   // Turn off autofill profile sync.
   auto model_type_set = sync_service_.GetActiveDataTypes();
@@ -6726,9 +6729,7 @@
   test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox", "123 Zoo St", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
-  personal_data_->AddProfile(profile);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile);
 
   std::vector<std::unique_ptr<AutofillProfile>> profiles;
   // Expect that a profile is stored in the profile autofill table.
@@ -6822,7 +6823,7 @@
   // Create three profiles and add them to personal_data_.
   AutofillProfile valid_profile(test::GetFullValidProfileForCanada());
   valid_profile.set_guid("00000000-0000-0000-0000-000000000001");
-  personal_data_->AddProfile(valid_profile);
+  AddProfileToPersonalDataManager(valid_profile);
 
   AutofillProfile profile_invalid_phone_email(
       test::GetFullValidProfileForChina());
@@ -6831,7 +6832,7 @@
   profile_invalid_phone_email.SetRawInfo(EMAIL_ADDRESS,
                                          base::UTF8ToUTF16("invalid email!"));
   profile_invalid_phone_email.set_guid("00000000-0000-0000-0000-000000000002");
-  personal_data_->AddProfile(profile_invalid_phone_email);
+  AddProfileToPersonalDataManager(profile_invalid_phone_email);
 
   AutofillProfile profile_invalid_province(base::GenerateGUID(),
                                            test::kEmptyOrigin);
@@ -6839,9 +6840,8 @@
                        "alice@munro.ca", "Fox", "123 Zoo St", "unit 5",
                        "Montreal", "CA", "H3C 2A3", "CA", "15142343254");
   profile_invalid_province.set_guid("00000000-0000-0000-0000-000000000003");
-  personal_data_->AddProfile(profile_invalid_province);
+  AddProfileToPersonalDataManager(profile_invalid_province);
 
-  WaitForOnPersonalDataChanged();
   ASSERT_EQ(3U, personal_data_->GetProfiles().size());
 
   // Validate the profiles through the client validation API.
@@ -6935,12 +6935,11 @@
 TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
   // Create two profiles and add them to personal_data_.
   AutofillProfile profile1(test::GetFullValidProfileForCanada());
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(test::GetFullValidProfileForChina());
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
-  WaitForOnPersonalDataChanged();
   ASSERT_EQ(2U, personal_data_->GetProfiles().size());
 
   // Validate the profiles through the client validation API.
@@ -6983,13 +6982,11 @@
   // Create two profiles and add them to personal_data_.
   AutofillProfile profile1(test::GetFullValidProfileForCanada());
   profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(test::GetFullValidProfileForChina());
   profile2.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("invalid state!"));
-  personal_data_->AddProfile(profile2);
-
-  WaitForOnPersonalDataChanged();
+  AddProfileToPersonalDataManager(profile2);
 
   EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
 
@@ -7026,14 +7023,13 @@
   AutofillProfile profile1(test::GetFullValidProfileForCanada());
   profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
   profile1.set_guid("00000000-0000-0000-0000-000000000001");
-  personal_data_->AddProfile(profile1);
+  AddProfileToPersonalDataManager(profile1);
 
   AutofillProfile profile2(test::GetFullValidProfileForChina());
   profile2.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("invalid state!"));
   profile2.set_guid("00000000-0000-0000-0000-000000000002");
-  personal_data_->AddProfile(profile2);
+  AddProfileToPersonalDataManager(profile2);
 
-  WaitForOnPersonalDataChanged();
   auto profiles = personal_data_->GetProfiles();
 
   // Pretend that the validity states are updated.
diff --git a/components/autofill/core/browser/webdata/autofill_change.h b/components/autofill/core/browser/webdata/autofill_change.h
index af764ed..600692e 100644
--- a/components/autofill/core/browser/webdata/autofill_change.h
+++ b/components/autofill/core/browser/webdata/autofill_change.h
@@ -9,11 +9,11 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/webdata/autofill_entry.h"
 
 namespace autofill {
 
-class AutofillProfile;
 class CreditCard;
 
 // For classic Autofill form fields, the KeyType is AutofillKey.
@@ -88,6 +88,25 @@
 typedef AutofillDataModelChange<AutofillProfile> AutofillProfileChange;
 typedef AutofillDataModelChange<CreditCard> CreditCardChange;
 
+class AutofillProfileDeepChange : public AutofillProfileChange {
+ public:
+  AutofillProfileDeepChange(Type type, const AutofillProfile& profile)
+      : AutofillProfileChange(type, profile.guid(), &profile),
+        profile_(profile) {}
+
+  AutofillProfileDeepChange(Type type, const std::string& guid)
+      : AutofillProfileChange(type, guid, nullptr), profile_(guid, "") {
+    DCHECK(type == GenericAutofillChange::REMOVE);
+  }
+
+  ~AutofillProfileDeepChange() override {}
+
+  AutofillProfile profile() const { return profile_; }
+
+ private:
+  AutofillProfile profile_;
+};
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_CHANGE_H__
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
index 3c4deea..edc03da 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -15,6 +15,7 @@
 #include "components/autofill/core/browser/webdata/autofill_change.h"
 #include "components/autofill/core/browser/webdata/autofill_entry.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/webdata/common/web_database_backend.h"
@@ -53,6 +54,11 @@
   DCHECK(!user_data_);  // Forgot to call ResetUserData?
 }
 
+void AutofillWebDataBackendImpl::SetAutofillProfileChangedCallback(
+    base::RepeatingCallback<void(const AutofillProfileDeepChange&)> change_cb) {
+  on_autofill_profile_changed_cb_ = std::move(change_cb);
+}
+
 WebDatabase* AutofillWebDataBackendImpl::GetDatabase() {
   DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
   return web_database_backend_->database();
@@ -202,6 +208,13 @@
   for (auto& db_observer : db_observer_list_)
     db_observer.AutofillProfileChanged(change);
 
+  if (!on_autofill_profile_changed_cb_.is_null()) {
+    ui_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(on_autofill_profile_changed_cb_,
+                                  AutofillProfileDeepChange(
+                                      AutofillProfileChange::ADD, profile)));
+  }
+
   return WebDatabase::COMMIT_NEEDED;
 }
 
@@ -227,6 +240,13 @@
   for (auto& db_observer : db_observer_list_)
     db_observer.AutofillProfileChanged(change);
 
+  if (!on_autofill_profile_changed_cb_.is_null()) {
+    ui_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(on_autofill_profile_changed_cb_,
+                                  AutofillProfileDeepChange(
+                                      AutofillProfileChange::UPDATE, profile)));
+  }
+
   return WebDatabase::COMMIT_NEEDED;
 }
 
@@ -250,6 +270,13 @@
   for (auto& db_observer : db_observer_list_)
     db_observer.AutofillProfileChanged(change);
 
+  if (!on_autofill_profile_changed_cb_.is_null()) {
+    ui_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(on_autofill_profile_changed_cb_,
+                                  AutofillProfileDeepChange(
+                                      AutofillProfileChange::REMOVE, guid)));
+  }
+
   return WebDatabase::COMMIT_NEEDED;
 }
 
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
index 064d7ec..41b5861 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
@@ -55,6 +55,10 @@
       const base::Closure& on_changed_callback,
       const base::Callback<void(syncer::ModelType)>& on_sync_started_callback);
 
+  void SetAutofillProfileChangedCallback(
+      base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
+          change_cb);
+
   // AutofillWebDataBackend implementation.
   void AddObserver(
       AutofillWebDataServiceObserverOnDBSequence* observer) override;
@@ -230,6 +234,9 @@
   base::Closure on_changed_callback_;
   base::Callback<void(syncer::ModelType)> on_sync_started_callback_;
 
+  base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
+      on_autofill_profile_changed_cb_;
+
   DISALLOW_COPY_AND_ASSIGN(AutofillWebDataBackendImpl);
 };
 
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service.cc b/components/autofill/core/browser/webdata/autofill_webdata_service.cc
index dd40364..2e4bda52 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_service.cc
@@ -107,6 +107,11 @@
            autofill_backend_, profile));
 }
 
+void AutofillWebDataService::SetAutofillProfileChangedCallback(
+    base::RepeatingCallback<void(const AutofillProfileDeepChange&)> change_cb) {
+  autofill_backend_->SetAutofillProfileChangedCallback(std::move(change_cb));
+}
+
 void AutofillWebDataService::UpdateAutofillProfile(
     const AutofillProfile& profile) {
   wdbs_->ScheduleDBTask(FROM_HERE,
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service.h b/components/autofill/core/browser/webdata/autofill_webdata_service.h
index a1db37c..c40ad6108 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_service.h
+++ b/components/autofill/core/browser/webdata/autofill_webdata_service.h
@@ -12,6 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/supports_user_data.h"
+#include "components/autofill/core/browser/webdata/autofill_change.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/sync/base/model_type.h"
@@ -83,6 +84,10 @@
   void UpdateAutofillEntries(
       const std::vector<AutofillEntry>& autofill_entries) override;
 
+  void SetAutofillProfileChangedCallback(
+      base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
+          change_cb);
+
   // Credit cards.
   void AddCreditCard(const CreditCard& credit_card) override;
   void UpdateCreditCard(const CreditCard& credit_card) override;
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h b/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h
index 94805a9..7477ce7 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h
+++ b/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h
@@ -37,6 +37,8 @@
   // Sync.
   virtual void AutofillMultipleChanged() {}
 
+  virtual void AutofillProfileChanged(const AutofillProfileChange& change) {}
+
   // Called on UI sequence when sync has started for |model_type|.
   virtual void SyncStarted(syncer::ModelType /* model_type */) {}