Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / password_manager / chrome_password_manager_client.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
6
7 #include "base/bind_helpers.h"
8 #include "base/command_line.h"
9 #include "base/memory/singleton.h"
10 #include "base/metrics/histogram.h"
11 #include "chrome/browser/password_manager/password_manager_util.h"
12 #include "chrome/browser/password_manager/password_store_factory.h"
13 #include "chrome/browser/password_manager/save_password_infobar_delegate.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/sync/profile_sync_service.h"
16 #include "chrome/browser/sync/profile_sync_service_factory.h"
17 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h"
18 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/chrome_version_info.h"
21 #include "components/autofill/content/common/autofill_messages.h"
22 #include "components/autofill/core/browser/password_generator.h"
23 #include "components/autofill/core/common/password_form.h"
24 #include "components/password_manager/core/browser/password_form_manager.h"
25 #include "components/password_manager/core/browser/password_manager.h"
26 #include "components/password_manager/core/browser/password_manager_logger.h"
27 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
28 #include "components/password_manager/core/common/password_manager_switches.h"
29 #include "content/public/browser/render_view_host.h"
30 #include "content/public/browser/web_contents.h"
31
32 #if defined(OS_ANDROID)
33 #include "chrome/browser/android/password_authentication_manager.h"
34 #endif  // OS_ANDROID
35
36 namespace {
37
38 bool IsTheHotNewBubbleUIEnabled() {
39   std::string group_name =
40       base::FieldTrialList::FindFullName("PasswordManagerUI");
41
42   CommandLine* command_line = CommandLine::ForCurrentProcess();
43   if (command_line->HasSwitch(switches::kDisableSavePasswordBubble))
44     return false;
45
46   if (command_line->HasSwitch(switches::kEnableSavePasswordBubble))
47     return true;
48
49   return group_name == "Bubble";
50 }
51
52 } // namespace
53
54 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromePasswordManagerClient);
55
56 // static
57 void
58 ChromePasswordManagerClient::CreateForWebContentsWithAutofillManagerDelegate(
59     content::WebContents* contents,
60     autofill::AutofillManagerDelegate* delegate) {
61   if (FromWebContents(contents))
62     return;
63
64   contents->SetUserData(UserDataKey(),
65                         new ChromePasswordManagerClient(contents, delegate));
66 }
67
68 ChromePasswordManagerClient::ChromePasswordManagerClient(
69     content::WebContents* web_contents,
70     autofill::AutofillManagerDelegate* autofill_manager_delegate)
71     : content::WebContentsObserver(web_contents),
72       driver_(web_contents, this, autofill_manager_delegate),
73       observer_(NULL),
74       weak_factory_(this),
75       logger_(NULL) {}
76
77 ChromePasswordManagerClient::~ChromePasswordManagerClient() {}
78
79 bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
80   return CommandLine::ForCurrentProcess()->HasSwitch(
81              password_manager::switches::kEnableAutomaticPasswordSaving) &&
82          chrome::VersionInfo::GetChannel() ==
83              chrome::VersionInfo::CHANNEL_UNKNOWN;
84 }
85
86 void ChromePasswordManagerClient::PromptUserToSavePassword(
87     password_manager::PasswordFormManager* form_to_save) {
88   if (IsTheHotNewBubbleUIEnabled()) {
89     ManagePasswordsUIController* manage_passwords_ui_controller =
90         ManagePasswordsUIController::FromWebContents(web_contents());
91     if (manage_passwords_ui_controller) {
92       manage_passwords_ui_controller->OnPasswordSubmitted(form_to_save);
93     } else {
94       delete form_to_save;
95     }
96   } else {
97     std::string uma_histogram_suffix(
98         password_manager::metrics_util::GroupIdToString(
99             password_manager::metrics_util::MonitoredDomainGroupId(
100                 form_to_save->realm(), GetPrefs())));
101     SavePasswordInfoBarDelegate::Create(
102         web_contents(), form_to_save, uma_histogram_suffix);
103   }
104 }
105
106 void ChromePasswordManagerClient::PasswordWasAutofilled(
107     const autofill::PasswordFormMap& best_matches) const {
108   ManagePasswordsUIController* manage_passwords_ui_controller =
109       ManagePasswordsUIController::FromWebContents(web_contents());
110   if (manage_passwords_ui_controller && IsTheHotNewBubbleUIEnabled())
111     manage_passwords_ui_controller->OnPasswordAutofilled(best_matches);
112 }
113
114 void ChromePasswordManagerClient::PasswordAutofillWasBlocked(
115     const autofill::PasswordFormMap& best_matches) const {
116   ManagePasswordsUIController* controller =
117       ManagePasswordsUIController::FromWebContents(web_contents());
118   if (controller && IsTheHotNewBubbleUIEnabled())
119     controller->OnBlacklistBlockedAutofill(best_matches);
120 }
121
122 void ChromePasswordManagerClient::AuthenticateAutofillAndFillForm(
123       scoped_ptr<autofill::PasswordFormFillData> fill_data) {
124 #if defined(OS_ANDROID)
125   PasswordAuthenticationManager::AuthenticatePasswordAutofill(
126       web_contents(),
127       base::Bind(&ChromePasswordManagerClient::CommitFillPasswordForm,
128                  weak_factory_.GetWeakPtr(),
129                  base::Owned(fill_data.release())));
130 #else
131   // Additional authentication is currently only available for Android, so all
132   // other plaftorms should just fill the password form directly.
133   CommitFillPasswordForm(fill_data.get());
134 #endif  // OS_ANDROID
135 }
136
137 Profile* ChromePasswordManagerClient::GetProfile() {
138   return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
139 }
140
141 void ChromePasswordManagerClient::HidePasswordGenerationPopup() {
142   if (popup_controller_)
143     popup_controller_->HideAndDestroy();
144 }
145
146 PrefService* ChromePasswordManagerClient::GetPrefs() {
147   return GetProfile()->GetPrefs();
148 }
149
150 password_manager::PasswordStore*
151 ChromePasswordManagerClient::GetPasswordStore() {
152   // Always use EXPLICIT_ACCESS as the password manager checks IsOffTheRecord
153   // itself when it shouldn't access the PasswordStore.
154   // TODO(gcasto): Is is safe to change this to Profile::IMPLICIT_ACCESS?
155   return PasswordStoreFactory::GetForProfile(GetProfile(),
156                                              Profile::EXPLICIT_ACCESS).get();
157 }
158
159 password_manager::PasswordManagerDriver*
160 ChromePasswordManagerClient::GetDriver() {
161   return &driver_;
162 }
163
164 base::FieldTrial::Probability
165 ChromePasswordManagerClient::GetProbabilityForExperiment(
166     const std::string& experiment_name) {
167   base::FieldTrial::Probability enabled_probability = 0;
168   if (experiment_name ==
169       password_manager::PasswordManager::kOtherPossibleUsernamesExperiment) {
170     switch (chrome::VersionInfo::GetChannel()) {
171       case chrome::VersionInfo::CHANNEL_DEV:
172       case chrome::VersionInfo::CHANNEL_BETA:
173         enabled_probability = 50;
174         break;
175       default:
176         break;
177     }
178   }
179   return enabled_probability;
180 }
181
182 bool ChromePasswordManagerClient::IsPasswordSyncEnabled() {
183   ProfileSyncService* sync_service =
184       ProfileSyncServiceFactory::GetForProfile(GetProfile());
185   // Don't consider sync enabled if the user has a custom passphrase. See
186   // crbug.com/358998 for more details.
187   if (sync_service &&
188       sync_service->HasSyncSetupCompleted() &&
189       sync_service->sync_initialized() &&
190       !sync_service->IsUsingSecondaryPassphrase()) {
191     return sync_service->GetActiveDataTypes().Has(syncer::PASSWORDS);
192   }
193   return false;
194 }
195
196 void ChromePasswordManagerClient::SetLogger(
197     password_manager::PasswordManagerLogger* logger) {
198   // We should never be replacing one logger with a different one, because that
199   // will leave the first without further updates, and the user likely confused.
200   // TODO(vabr): For the reason above, before moving the internals page from
201   // behind the flag, make sure to restrict the number of internals page
202   // instances to 1 in normal profiles, and 0 in incognito.
203   DCHECK(!logger || !logger_);
204   logger_ = logger;
205
206   // Also inform the renderer process to start or stop logging.
207   web_contents()->GetRenderViewHost()->Send(new AutofillMsg_ChangeLoggingState(
208       web_contents()->GetRenderViewHost()->GetRoutingID(), logger != NULL));
209 }
210
211 void ChromePasswordManagerClient::LogSavePasswordProgress(
212     const std::string& text) {
213   if (IsLoggingActive())
214     logger_->LogSavePasswordProgress(text);
215 }
216
217 bool ChromePasswordManagerClient::IsLoggingActive() const {
218   return logger_ != NULL;
219 }
220
221 // static
222 password_manager::PasswordGenerationManager*
223 ChromePasswordManagerClient::GetGenerationManagerFromWebContents(
224     content::WebContents* contents) {
225   ChromePasswordManagerClient* client =
226       ChromePasswordManagerClient::FromWebContents(contents);
227   if (!client)
228     return NULL;
229   return client->GetDriver()->GetPasswordGenerationManager();
230 }
231
232 // static
233 password_manager::PasswordManager*
234 ChromePasswordManagerClient::GetManagerFromWebContents(
235     content::WebContents* contents) {
236   ChromePasswordManagerClient* client =
237       ChromePasswordManagerClient::FromWebContents(contents);
238   if (!client)
239     return NULL;
240   return client->GetDriver()->GetPasswordManager();
241 }
242
243 void ChromePasswordManagerClient::SetTestObserver(
244     autofill::PasswordGenerationPopupObserver* observer) {
245   observer_ = observer;
246 }
247
248 bool ChromePasswordManagerClient::OnMessageReceived(
249     const IPC::Message& message) {
250   bool handled = true;
251   IPC_BEGIN_MESSAGE_MAP(ChromePasswordManagerClient, message)
252     IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordGenerationPopup,
253                         ShowPasswordGenerationPopup)
254     IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordEditingPopup,
255                         ShowPasswordEditingPopup)
256     IPC_MESSAGE_HANDLER(AutofillHostMsg_HidePasswordGenerationPopup,
257                         HidePasswordGenerationPopup)
258     IPC_MESSAGE_UNHANDLED(handled = false)
259   IPC_END_MESSAGE_MAP()
260   return handled;
261 }
262
263 gfx::RectF ChromePasswordManagerClient::GetBoundsInScreenSpace(
264     const gfx::RectF& bounds) {
265   gfx::Rect client_area = web_contents()->GetContainerBounds();
266   return bounds + client_area.OffsetFromOrigin();
267 }
268
269 void ChromePasswordManagerClient::ShowPasswordGenerationPopup(
270     const gfx::RectF& bounds,
271     int max_length,
272     const autofill::PasswordForm& form) {
273   // TODO(gcasto): Validate data in PasswordForm.
274
275   // Only implemented for Aura right now.
276 #if defined(USE_AURA)
277   gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
278
279   popup_controller_ =
280       autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
281           popup_controller_,
282           element_bounds_in_screen_space,
283           form,
284           max_length,
285           driver_.GetPasswordManager(),
286           observer_,
287           web_contents(),
288           web_contents()->GetNativeView());
289   popup_controller_->Show(true /* display_password */);
290 #endif  // #if defined(USE_AURA)
291 }
292
293 void ChromePasswordManagerClient::ShowPasswordEditingPopup(
294     const gfx::RectF& bounds,
295     const autofill::PasswordForm& form) {
296   // Only implemented for Aura right now.
297 #if defined(USE_AURA)
298   gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
299
300   popup_controller_ =
301       autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
302           popup_controller_,
303           element_bounds_in_screen_space,
304           form,
305           0,  // Unspecified max length.
306           driver_.GetPasswordManager(),
307           observer_,
308           web_contents(),
309           web_contents()->GetNativeView());
310   popup_controller_->Show(false /* display_password */);
311 #endif  // #if defined(USE_AURA)
312 }
313
314 void ChromePasswordManagerClient::CommitFillPasswordForm(
315     autofill::PasswordFormFillData* data) {
316   driver_.FillPasswordForm(*data);
317 }