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

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

Powered by Google App Engine
This is Rietveld 408576698