Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: chrome/browser/password_manager/password_store_mac.cc

Issue 838453003: Open the LoginDatabase on the DB thread, not the UI thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix nits, rework unittests. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/password_manager/password_store_mac.h" 5 #include "chrome/browser/password_manager/password_store_mac.h"
6 #include "chrome/browser/password_manager/password_store_mac_internal.h" 6 #include "chrome/browser/password_manager/password_store_mac_internal.h"
7 7
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 856
857 OSType MacKeychainPasswordFormAdapter::CreatorCodeForSearch() { 857 OSType MacKeychainPasswordFormAdapter::CreatorCodeForSearch() {
858 return finds_only_owned_ ? base::mac::CreatorCodeForApplication() : 0; 858 return finds_only_owned_ ? base::mac::CreatorCodeForApplication() : 0;
859 } 859 }
860 860
861 #pragma mark - 861 #pragma mark -
862 862
863 PasswordStoreMac::PasswordStoreMac( 863 PasswordStoreMac::PasswordStoreMac(
864 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, 864 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
865 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner, 865 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner,
866 AppleKeychain* keychain, 866 scoped_ptr<AppleKeychain> keychain,
867 password_manager::LoginDatabase* login_db) 867 scoped_ptr<password_manager::LoginDatabase> login_db)
868 : password_manager::PasswordStore(main_thread_runner, db_thread_runner), 868 : password_manager::PasswordStore(main_thread_runner, db_thread_runner),
869 keychain_(keychain), 869 keychain_(keychain.Pass()),
870 login_metadata_db_(login_db) { 870 login_metadata_db_(login_db.Pass()) {
871 DCHECK(keychain_.get()); 871 DCHECK(keychain_.get());
872 DCHECK(login_metadata_db_.get()); 872 DCHECK(login_metadata_db_.get());
873 } 873 }
874 874
875 PasswordStoreMac::~PasswordStoreMac() {} 875 PasswordStoreMac::~PasswordStoreMac() {}
876 876
877 bool PasswordStoreMac::Init( 877 bool PasswordStoreMac::Init(
878 const syncer::SyncableService::StartSyncFlare& flare) { 878 const syncer::SyncableService::StartSyncFlare& flare) {
879 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 879 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
880 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread")); 880 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
881 881
882 if (!thread_->Start()) { 882 if (!thread_->Start()) {
883 thread_.reset(NULL); 883 thread_.reset(NULL);
884 return false; 884 return false;
885 } 885 }
886
887 ScheduleTask(base::Bind(&PasswordStoreMac::InitOnBackgroundThread, this));
886 return password_manager::PasswordStore::Init(flare); 888 return password_manager::PasswordStore::Init(flare);
887 } 889 }
888 890
891 void PasswordStoreMac::InitOnBackgroundThread() {
892 DCHECK(thread_->message_loop() == base::MessageLoop::current());
893 DCHECK(login_metadata_db_);
894 if (!login_metadata_db_->Init()) {
895 login_metadata_db_.reset();
896 LOG(ERROR) << "Could not create/open login database.";
897 }
898 }
899
889 void PasswordStoreMac::Shutdown() { 900 void PasswordStoreMac::Shutdown() {
890 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 901 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
891 password_manager::PasswordStore::Shutdown(); 902 password_manager::PasswordStore::Shutdown();
892 thread_->Stop(); 903 thread_->Stop();
893 } 904 }
894 905
895 // Mac stores passwords in the system keychain, which can block for an 906 // Mac stores passwords in the system keychain, which can block for an
896 // arbitrarily long time (most notably, it can block on user confirmation 907 // arbitrarily long time (most notably, it can block on user confirmation
897 // from a dialog). Run tasks on a dedicated thread to avoid blocking the DB 908 // from a dialog). Run tasks on a dedicated thread to avoid blocking the DB
898 // thread. 909 // thread.
899 scoped_refptr<base::SingleThreadTaskRunner> 910 scoped_refptr<base::SingleThreadTaskRunner>
900 PasswordStoreMac::GetBackgroundTaskRunner() { 911 PasswordStoreMac::GetBackgroundTaskRunner() {
901 return (thread_.get()) ? thread_->message_loop_proxy() : NULL; 912 return (thread_.get()) ? thread_->message_loop_proxy() : NULL;
902 } 913 }
903 914
904 void PasswordStoreMac::ReportMetricsImpl(const std::string& sync_username, 915 void PasswordStoreMac::ReportMetricsImpl(const std::string& sync_username,
905 bool custom_passphrase_sync_enabled) { 916 bool custom_passphrase_sync_enabled) {
917 if (!login_metadata_db_)
918 return;
906 login_metadata_db_->ReportMetrics(sync_username, 919 login_metadata_db_->ReportMetrics(sync_username,
907 custom_passphrase_sync_enabled); 920 custom_passphrase_sync_enabled);
908 } 921 }
909 922
910 PasswordStoreChangeList PasswordStoreMac::AddLoginImpl( 923 PasswordStoreChangeList PasswordStoreMac::AddLoginImpl(
911 const PasswordForm& form) { 924 const PasswordForm& form) {
912 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 925 DCHECK(thread_->message_loop() == base::MessageLoop::current());
913 PasswordStoreChangeList changes; 926 if (login_metadata_db_ && AddToKeychainIfNecessary(form))
914 if (AddToKeychainIfNecessary(form)) { 927 return login_metadata_db_->AddLogin(form);
915 changes = login_metadata_db_->AddLogin(form); 928 return PasswordStoreChangeList();
916 }
917 return changes;
918 } 929 }
919 930
920 PasswordStoreChangeList PasswordStoreMac::UpdateLoginImpl( 931 PasswordStoreChangeList PasswordStoreMac::UpdateLoginImpl(
921 const PasswordForm& form) { 932 const PasswordForm& form) {
922 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 933 DCHECK(thread_->message_loop() == base::MessageLoop::current());
934 if (!login_metadata_db_)
935 return PasswordStoreChangeList();
936
923 PasswordStoreChangeList changes = login_metadata_db_->UpdateLogin(form); 937 PasswordStoreChangeList changes = login_metadata_db_->UpdateLogin(form);
924 938
925 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get()); 939 MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get());
926 if (changes.empty() && 940 if (changes.empty() &&
927 !keychain_adapter.HasPasswordsMergeableWithForm(form)) { 941 !keychain_adapter.HasPasswordsMergeableWithForm(form)) {
928 // If the password isn't in either the DB or the keychain, then it must have 942 // If the password isn't in either the DB or the keychain, then it must have
929 // been deleted after autofill happened, and should not be re-added. 943 // been deleted after autofill happened, and should not be re-added.
930 return changes; 944 return changes;
931 } 945 }
932 946
933 // The keychain add will update if there is a collision and add if there 947 // The keychain add will update if there is a collision and add if there
934 // isn't, which is the behavior we want, so there's no separate update call. 948 // isn't, which is the behavior we want, so there's no separate update call.
935 if (AddToKeychainIfNecessary(form) && changes.empty()) { 949 if (AddToKeychainIfNecessary(form) && changes.empty()) {
936 changes = login_metadata_db_->AddLogin(form); 950 changes = login_metadata_db_->AddLogin(form);
937 } 951 }
938 return changes; 952 return changes;
939 } 953 }
940 954
941 PasswordStoreChangeList PasswordStoreMac::RemoveLoginImpl( 955 PasswordStoreChangeList PasswordStoreMac::RemoveLoginImpl(
942 const PasswordForm& form) { 956 const PasswordForm& form) {
943 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 957 DCHECK(thread_->message_loop() == base::MessageLoop::current());
944 PasswordStoreChangeList changes; 958 PasswordStoreChangeList changes;
945 if (login_metadata_db_->RemoveLogin(form)) { 959 if (login_metadata_db_ && login_metadata_db_->RemoveLogin(form)) {
946 // See if we own a Keychain item associated with this item. We can do an 960 // See if we own a Keychain item associated with this item. We can do an
947 // exact search rather than messing around with trying to do fuzzy matching 961 // exact search rather than messing around with trying to do fuzzy matching
948 // because passwords that we created will always have an exact-match 962 // because passwords that we created will always have an exact-match
949 // database entry. 963 // database entry.
950 // (If a user does lose their profile but not their keychain we'll treat the 964 // (If a user does lose their profile but not their keychain we'll treat the
951 // entries we find like other imported entries anyway, so it's reasonable to 965 // entries we find like other imported entries anyway, so it's reasonable to
952 // handle deletes on them the way we would for an imported item.) 966 // handle deletes on them the way we would for an imported item.)
953 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); 967 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
954 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 968 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
955 if (owned_keychain_adapter.HasPasswordExactlyMatchingForm(form)) { 969 if (owned_keychain_adapter.HasPasswordExactlyMatchingForm(form)) {
956 // If we don't have other forms using it (i.e., a form differing only by 970 // If we don't have other forms using it (i.e., a form differing only by
957 // the names of the form elements), delete the keychain entry. 971 // the names of the form elements), delete the keychain entry.
958 if (!DatabaseHasFormMatchingKeychainForm(form)) { 972 if (!DatabaseHasFormMatchingKeychainForm(form)) {
959 owned_keychain_adapter.RemovePassword(form); 973 owned_keychain_adapter.RemovePassword(form);
960 } 974 }
961 } 975 }
962 976
963 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); 977 changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
964 } 978 }
965 return changes; 979 return changes;
966 } 980 }
967 981
968 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl( 982 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsCreatedBetweenImpl(
969 base::Time delete_begin, 983 base::Time delete_begin,
970 base::Time delete_end) { 984 base::Time delete_end) {
971 PasswordStoreChangeList changes; 985 PasswordStoreChangeList changes;
972 ScopedVector<PasswordForm> forms; 986 ScopedVector<PasswordForm> forms;
973 if (login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end, 987 if (login_metadata_db_ &&
974 &forms.get())) { 988 login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end,
975 if (login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin, 989 &forms.get()) &&
976 delete_end)) { 990 login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin,
977 RemoveKeychainForms(forms.get()); 991 delete_end)) {
978 CleanOrphanedForms(&forms.get()); 992 RemoveKeychainForms(forms.get());
979 changes = FormsToRemoveChangeList(forms.get()); 993 CleanOrphanedForms(&forms.get());
980 LogStatsForBulkDeletion(changes.size()); 994 changes = FormsToRemoveChangeList(forms.get());
981 } 995 LogStatsForBulkDeletion(changes.size());
982 } 996 }
983 return changes; 997 return changes;
984 } 998 }
985 999
986 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl( 1000 PasswordStoreChangeList PasswordStoreMac::RemoveLoginsSyncedBetweenImpl(
987 base::Time delete_begin, 1001 base::Time delete_begin,
988 base::Time delete_end) { 1002 base::Time delete_end) {
989 PasswordStoreChangeList changes; 1003 PasswordStoreChangeList changes;
990 ScopedVector<PasswordForm> forms; 1004 ScopedVector<PasswordForm> forms;
991 if (login_metadata_db_->GetLoginsSyncedBetween( 1005 if (login_metadata_db_ &&
992 delete_begin, delete_end, &forms.get())) { 1006 login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end,
993 if (login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, 1007 &forms.get()) &&
994 delete_end)) { 1008 login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) {
995 RemoveKeychainForms(forms.get()); 1009 RemoveKeychainForms(forms.get());
996 CleanOrphanedForms(&forms.get()); 1010 CleanOrphanedForms(&forms.get());
997 changes = FormsToRemoveChangeList(forms.get()); 1011 changes = FormsToRemoveChangeList(forms.get());
998 LogStatsForBulkDeletionDuringRollback(changes.size()); 1012 LogStatsForBulkDeletionDuringRollback(changes.size());
999 }
1000 } 1013 }
1001 return changes; 1014 return changes;
1002 } 1015 }
1003 1016
1004 void PasswordStoreMac::GetLoginsImpl( 1017 void PasswordStoreMac::GetLoginsImpl(
1005 const autofill::PasswordForm& form, 1018 const autofill::PasswordForm& form,
1006 AuthorizationPromptPolicy prompt_policy, 1019 AuthorizationPromptPolicy prompt_policy,
1007 const ConsumerCallbackRunner& callback_runner) { 1020 const ConsumerCallbackRunner& callback_runner) {
1008 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed( 1021 chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(
1009 prompt_policy == ALLOW_PROMPT); 1022 prompt_policy == ALLOW_PROMPT);
1010 1023
1024 if (!login_metadata_db_) {
1025 callback_runner.Run(std::vector<PasswordForm*>());
1026 return;
1027 }
1028
1011 ScopedVector<PasswordForm> database_forms; 1029 ScopedVector<PasswordForm> database_forms;
1012 login_metadata_db_->GetLogins(form, &database_forms.get()); 1030 login_metadata_db_->GetLogins(form, &database_forms.get());
1013 1031
1014 // Let's gather all signon realms we want to match with keychain entries. 1032 // Let's gather all signon realms we want to match with keychain entries.
1015 std::set<std::string> realm_set; 1033 std::set<std::string> realm_set;
1016 realm_set.insert(form.signon_realm); 1034 realm_set.insert(form.signon_realm);
1017 for (std::vector<PasswordForm*>::const_iterator db_form = 1035 for (std::vector<PasswordForm*>::const_iterator db_form =
1018 database_forms.begin(); 1036 database_forms.begin();
1019 db_form != database_forms.end(); 1037 db_form != database_forms.end();
1020 ++db_form) { 1038 ++db_form) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) { 1087 void PasswordStoreMac::GetAutofillableLoginsImpl(GetLoginsRequest* request) {
1070 FillAutofillableLogins(request->result()); 1088 FillAutofillableLogins(request->result());
1071 ForwardLoginsResult(request); 1089 ForwardLoginsResult(request);
1072 } 1090 }
1073 1091
1074 bool PasswordStoreMac::FillAutofillableLogins( 1092 bool PasswordStoreMac::FillAutofillableLogins(
1075 std::vector<PasswordForm*>* forms) { 1093 std::vector<PasswordForm*>* forms) {
1076 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 1094 DCHECK(thread_->message_loop() == base::MessageLoop::current());
1077 1095
1078 ScopedVector<PasswordForm> database_forms; 1096 ScopedVector<PasswordForm> database_forms;
1079 if (!login_metadata_db_->GetAutofillableLogins(&database_forms.get())) 1097 if (!login_metadata_db_ ||
1098 !login_metadata_db_->GetAutofillableLogins(&database_forms.get()))
1080 return false; 1099 return false;
1081 1100
1082 std::vector<PasswordForm*> merged_forms = 1101 std::vector<PasswordForm*> merged_forms =
1083 internal_keychain_helpers::GetPasswordsForForms(*keychain_, 1102 internal_keychain_helpers::GetPasswordsForForms(*keychain_,
1084 &database_forms.get()); 1103 &database_forms.get());
1085 1104
1086 if (!database_forms.empty()) { 1105 if (!database_forms.empty()) {
1087 RemoveDatabaseForms(database_forms.get()); 1106 RemoveDatabaseForms(database_forms.get());
1088 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get())); 1107 NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get()));
1089 } 1108 }
1090 1109
1091 forms->insert(forms->end(), merged_forms.begin(), merged_forms.end()); 1110 forms->insert(forms->end(), merged_forms.begin(), merged_forms.end());
1092 return true; 1111 return true;
1093 } 1112 }
1094 1113
1095 bool PasswordStoreMac::FillBlacklistLogins( 1114 bool PasswordStoreMac::FillBlacklistLogins(
1096 std::vector<PasswordForm*>* forms) { 1115 std::vector<PasswordForm*>* forms) {
1097 DCHECK(thread_->message_loop() == base::MessageLoop::current()); 1116 DCHECK(thread_->message_loop() == base::MessageLoop::current());
1098 return login_metadata_db_->GetBlacklistLogins(forms); 1117 return login_metadata_db_ && login_metadata_db_->GetBlacklistLogins(forms);
1099 } 1118 }
1100 1119
1101 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { 1120 bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) {
1102 if (form.blacklisted_by_user) { 1121 if (form.blacklisted_by_user) {
1103 return true; 1122 return true;
1104 } 1123 }
1105 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); 1124 MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get());
1106 return keychainAdapter.AddPassword(form); 1125 return keychainAdapter.AddPassword(form);
1107 } 1126 }
1108 1127
1109 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm( 1128 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm(
1110 const autofill::PasswordForm& form) { 1129 const autofill::PasswordForm& form) {
1130 DCHECK(login_metadata_db_);
1111 bool has_match = false; 1131 bool has_match = false;
1112 std::vector<PasswordForm*> database_forms; 1132 std::vector<PasswordForm*> database_forms;
1113 login_metadata_db_->GetLogins(form, &database_forms); 1133 login_metadata_db_->GetLogins(form, &database_forms);
1114 for (std::vector<PasswordForm*>::iterator i = database_forms.begin(); 1134 for (std::vector<PasswordForm*>::iterator i = database_forms.begin();
1115 i != database_forms.end(); ++i) { 1135 i != database_forms.end(); ++i) {
1116 // Below we filter out forms with non-empty original_signon_realm, because 1136 // Below we filter out forms with non-empty original_signon_realm, because
1117 // those signal fuzzy matches, and we are only interested in exact ones. 1137 // those signal fuzzy matches, and we are only interested in exact ones.
1118 if ((*i)->original_signon_realm.empty() && 1138 if ((*i)->original_signon_realm.empty() &&
1119 internal_keychain_helpers::FormsMatchForMerge( 1139 internal_keychain_helpers::FormsMatchForMerge(
1120 form, **i, internal_keychain_helpers::STRICT_FORM_MATCH) && 1140 form, **i, internal_keychain_helpers::STRICT_FORM_MATCH) &&
1121 (*i)->origin == form.origin) { 1141 (*i)->origin == form.origin) {
1122 has_match = true; 1142 has_match = true;
1123 break; 1143 break;
1124 } 1144 }
1125 } 1145 }
1126 STLDeleteElements(&database_forms); 1146 STLDeleteElements(&database_forms);
1127 return has_match; 1147 return has_match;
1128 } 1148 }
1129 1149
1130 void PasswordStoreMac::RemoveDatabaseForms( 1150 void PasswordStoreMac::RemoveDatabaseForms(
1131 const std::vector<PasswordForm*>& forms) { 1151 const std::vector<PasswordForm*>& forms) {
1152 DCHECK(login_metadata_db_);
1132 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 1153 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
1133 i != forms.end(); ++i) { 1154 i != forms.end(); ++i) {
1134 login_metadata_db_->RemoveLogin(**i); 1155 login_metadata_db_->RemoveLogin(**i);
1135 } 1156 }
1136 } 1157 }
1137 1158
1138 void PasswordStoreMac::RemoveKeychainForms( 1159 void PasswordStoreMac::RemoveKeychainForms(
1139 const std::vector<PasswordForm*>& forms) { 1160 const std::vector<PasswordForm*>& forms) {
1140 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get()); 1161 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
1141 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 1162 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
1142 for (std::vector<PasswordForm*>::const_iterator i = forms.begin(); 1163 for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
1143 i != forms.end(); ++i) { 1164 i != forms.end(); ++i) {
1144 owned_keychain_adapter.RemovePassword(**i); 1165 owned_keychain_adapter.RemovePassword(**i);
1145 } 1166 }
1146 } 1167 }
1147 1168
1148 void PasswordStoreMac::CleanOrphanedForms(std::vector<PasswordForm*>* forms) { 1169 void PasswordStoreMac::CleanOrphanedForms(std::vector<PasswordForm*>* forms) {
1149 DCHECK(forms); 1170 DCHECK(forms);
1171 DCHECK(login_metadata_db_);
1172
1150 std::vector<PasswordForm*> database_forms; 1173 std::vector<PasswordForm*> database_forms;
1151 login_metadata_db_->GetAutofillableLogins(&database_forms); 1174 login_metadata_db_->GetAutofillableLogins(&database_forms);
1152 1175
1153 ScopedVector<PasswordForm> merged_forms; 1176 ScopedVector<PasswordForm> merged_forms;
1154 merged_forms.get() = internal_keychain_helpers::GetPasswordsForForms( 1177 merged_forms.get() = internal_keychain_helpers::GetPasswordsForForms(
1155 *keychain_, &database_forms); 1178 *keychain_, &database_forms);
1156 1179
1157 // Clean up any orphaned database entries. 1180 // Clean up any orphaned database entries.
1158 RemoveDatabaseForms(database_forms); 1181 RemoveDatabaseForms(database_forms);
1159 1182
1160 forms->insert(forms->end(), database_forms.begin(), database_forms.end()); 1183 forms->insert(forms->end(), database_forms.begin(), database_forms.end());
1161 } 1184 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698