OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ui/webui/options/create_profile_handler.h" | 5 #include "chrome/browser/ui/webui/options/create_profile_handler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/value_conversions.h" | 12 #include "base/value_conversions.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
15 #include "chrome/browser/profiles/profile_manager.h" | 15 #include "chrome/browser/profiles/profile_manager.h" |
16 #include "chrome/browser/profiles/profile_metrics.h" | 16 #include "chrome/browser/profiles/profile_metrics.h" |
17 #include "chrome/browser/profiles/profiles_state.h" | 17 #include "chrome/browser/profiles/profiles_state.h" |
| 18 #include "chrome/browser/sync/profile_sync_service.h" |
| 19 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 20 #include "chrome/browser/ui/webui/options/options_handlers_helper.h" |
| 21 #include "chrome/common/pref_names.h" |
| 22 #include "chrome/grit/generated_resources.h" |
| 23 #include "content/public/browser/web_ui.h" |
| 24 #include "ui/base/l10n/l10n_util.h" |
| 25 |
| 26 #if defined(ENABLE_MANAGED_USERS) |
18 #include "chrome/browser/supervised_user/supervised_user_registration_utility.h" | 27 #include "chrome/browser/supervised_user/supervised_user_registration_utility.h" |
19 #include "chrome/browser/supervised_user/supervised_user_service.h" | 28 #include "chrome/browser/supervised_user/supervised_user_service.h" |
20 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" | 29 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" |
21 #include "chrome/browser/supervised_user/supervised_user_sync_service.h" | 30 #include "chrome/browser/supervised_user/supervised_user_sync_service.h" |
22 #include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h" | 31 #include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h" |
23 #include "chrome/browser/sync/profile_sync_service.h" | 32 #endif |
24 #include "chrome/browser/sync/profile_sync_service_factory.h" | |
25 #include "chrome/browser/ui/webui/options/options_handlers_helper.h" | |
26 #include "chrome/common/pref_names.h" | |
27 #include "chrome/grit/generated_resources.h" | |
28 #include "ui/base/l10n/l10n_util.h" | |
29 | 33 |
30 namespace options { | 34 namespace options { |
31 | 35 |
32 CreateProfileHandler::CreateProfileHandler() | 36 CreateProfileHandler::CreateProfileHandler() |
33 : profile_creation_type_(NO_CREATION_IN_PROGRESS), | 37 : profile_creation_type_(NO_CREATION_IN_PROGRESS), |
34 weak_ptr_factory_(this) { | 38 weak_ptr_factory_(this) { |
35 } | 39 } |
36 | 40 |
37 CreateProfileHandler::~CreateProfileHandler() { | 41 CreateProfileHandler::~CreateProfileHandler() { |
| 42 #if defined(ENABLE_MANAGED_USERS) |
| 43 // Cancellation is only supported for supervised users. |
38 CancelProfileRegistration(false); | 44 CancelProfileRegistration(false); |
| 45 #endif |
39 } | 46 } |
40 | 47 |
41 void CreateProfileHandler::GetLocalizedValues( | 48 void CreateProfileHandler::GetLocalizedValues( |
42 base::DictionaryValue* localized_strings) { | 49 base::DictionaryValue* localized_strings) { |
43 } | 50 } |
44 | 51 |
45 void CreateProfileHandler::RegisterMessages() { | 52 void CreateProfileHandler::RegisterMessages() { |
| 53 #if defined(ENABLE_MANAGED_USERS) |
| 54 // Cancellation is only supported for supervised users. |
46 web_ui()->RegisterMessageCallback( | 55 web_ui()->RegisterMessageCallback( |
47 "cancelCreateProfile", | 56 "cancelCreateProfile", |
48 base::Bind(&CreateProfileHandler::HandleCancelProfileCreation, | 57 base::Bind(&CreateProfileHandler::HandleCancelProfileCreation, |
49 base::Unretained(this))); | 58 base::Unretained(this))); |
| 59 #endif |
50 web_ui()->RegisterMessageCallback( | 60 web_ui()->RegisterMessageCallback( |
51 "createProfile", | 61 "createProfile", |
52 base::Bind(&CreateProfileHandler::CreateProfile, | 62 base::Bind(&CreateProfileHandler::CreateProfile, |
53 base::Unretained(this))); | 63 base::Unretained(this))); |
54 } | 64 } |
55 | 65 |
56 void CreateProfileHandler::CreateProfile(const base::ListValue* args) { | 66 void CreateProfileHandler::CreateProfile(const base::ListValue* args) { |
| 67 #if defined(ENABLE_MANAGED_USERS) |
57 // This handler could have been called for a supervised user, for example | 68 // This handler could have been called for a supervised user, for example |
58 // because the user fiddled with the web inspector. Silently return in this | 69 // because the user fiddled with the web inspector. Silently return. |
59 // case. | 70 if (Profile::FromWebUI(web_ui())->IsSupervised()) |
60 Profile* current_profile = Profile::FromWebUI(web_ui()); | |
61 if (current_profile->IsSupervised()) | |
62 return; | 71 return; |
| 72 #endif |
63 | 73 |
64 if (!profiles::IsMultipleProfilesEnabled()) | 74 if (!profiles::IsMultipleProfilesEnabled()) |
65 return; | 75 return; |
66 | 76 |
67 // We can have only one in progress profile creation | 77 // We can have only one in progress profile creation |
68 // at any given moment, if new ones are initiated just | 78 // at any given moment, if new ones are initiated just |
69 // ignore them until we are done with the old one. | 79 // ignore them until we are done with the old one. |
70 if (profile_creation_type_ != NO_CREATION_IN_PROGRESS) | 80 if (profile_creation_type_ != NO_CREATION_IN_PROGRESS) |
71 return; | 81 return; |
72 | 82 |
73 profile_creation_type_ = NON_SUPERVISED_PROFILE_CREATION; | 83 profile_creation_type_ = NON_SUPERVISED_PROFILE_CREATION; |
74 | 84 |
75 DCHECK(profile_path_being_created_.empty()); | 85 DCHECK(profile_path_being_created_.empty()); |
76 profile_creation_start_time_ = base::TimeTicks::Now(); | 86 profile_creation_start_time_ = base::TimeTicks::Now(); |
77 | 87 |
78 base::string16 name; | 88 base::string16 name; |
79 base::string16 icon; | 89 base::string16 icon; |
80 std::string supervised_user_id; | |
81 bool create_shortcut = false; | 90 bool create_shortcut = false; |
82 bool supervised_user = false; | |
83 if (args->GetString(0, &name) && args->GetString(1, &icon)) { | 91 if (args->GetString(0, &name) && args->GetString(1, &icon)) { |
84 base::TrimWhitespace(name, base::TRIM_ALL, &name); | 92 base::TrimWhitespace(name, base::TRIM_ALL, &name); |
85 CHECK(!name.empty()); | 93 CHECK(!name.empty()); |
86 if (args->GetBoolean(2, &create_shortcut)) { | 94 args->GetBoolean(2, &create_shortcut); |
87 bool success = args->GetBoolean(3, &supervised_user); | |
88 DCHECK(success); | |
89 success = args->GetString(4, &supervised_user_id); | |
90 DCHECK(success); | |
91 } | |
92 } | 95 } |
93 | 96 std::string supervised_user_id; |
94 if (supervised_user) { | 97 #if defined(ENABLE_MANAGED_USERS) |
95 if (!IsValidExistingSupervisedUserId(supervised_user_id)) | 98 if (!ProcessSupervisedCreateProfileArgs(args, &supervised_user_id)) |
96 return; | 99 return; |
97 | 100 #endif |
98 profile_creation_type_ = SUPERVISED_PROFILE_IMPORT; | |
99 if (supervised_user_id.empty()) { | |
100 profile_creation_type_ = SUPERVISED_PROFILE_CREATION; | |
101 supervised_user_id = | |
102 SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(); | |
103 | |
104 // If sync is not yet fully initialized, the creation may take extra time, | |
105 // so show a message. Import doesn't wait for an acknowledgement, so it | |
106 // won't have the same potential delay. | |
107 ProfileSyncService* sync_service = | |
108 ProfileSyncServiceFactory::GetInstance()->GetForProfile( | |
109 current_profile); | |
110 ProfileSyncService::SyncStatusSummary status = | |
111 sync_service->QuerySyncStatusSummary(); | |
112 if (status == ProfileSyncService::DATATYPES_NOT_INITIALIZED) { | |
113 ShowProfileCreationWarning(l10n_util::GetStringUTF16( | |
114 IDS_PROFILES_CREATE_SUPERVISED_JUST_SIGNED_IN)); | |
115 } | |
116 } | |
117 } | |
118 | 101 |
119 ProfileMetrics::LogProfileAddNewUser(ProfileMetrics::ADD_NEW_USER_DIALOG); | 102 ProfileMetrics::LogProfileAddNewUser(ProfileMetrics::ADD_NEW_USER_DIALOG); |
120 | 103 |
121 profile_path_being_created_ = ProfileManager::CreateMultiProfileAsync( | 104 profile_path_being_created_ = ProfileManager::CreateMultiProfileAsync( |
122 name, icon, | 105 name, icon, |
123 base::Bind(&CreateProfileHandler::OnProfileCreated, | 106 base::Bind(&CreateProfileHandler::OnProfileCreated, |
124 weak_ptr_factory_.GetWeakPtr(), | 107 weak_ptr_factory_.GetWeakPtr(), |
125 create_shortcut, | 108 create_shortcut, |
126 helper::GetDesktopType(web_ui()), | 109 helper::GetDesktopType(web_ui()), |
127 supervised_user_id), | 110 supervised_user_id), |
128 supervised_user_id); | 111 supervised_user_id); |
129 } | 112 } |
130 | 113 |
131 void CreateProfileHandler::OnProfileCreated( | 114 void CreateProfileHandler::OnProfileCreated( |
132 bool create_shortcut, | 115 bool create_shortcut, |
133 chrome::HostDesktopType desktop_type, | 116 chrome::HostDesktopType desktop_type, |
134 const std::string& supervised_user_id, | 117 const std::string& supervised_user_id, |
135 Profile* profile, | 118 Profile* profile, |
136 Profile::CreateStatus status) { | 119 Profile::CreateStatus status) { |
137 if (status != Profile::CREATE_STATUS_CREATED) | 120 if (status != Profile::CREATE_STATUS_CREATED) |
138 RecordProfileCreationMetrics(status); | 121 RecordProfileCreationMetrics(status); |
139 | 122 |
140 switch (status) { | 123 switch (status) { |
141 case Profile::CREATE_STATUS_LOCAL_FAIL: { | 124 case Profile::CREATE_STATUS_LOCAL_FAIL: { |
142 ShowProfileCreationError(profile, | 125 ShowProfileCreationError(profile, GetProfileCreationErrorMessageLocal()); |
143 GetProfileCreationErrorMessage(LOCAL_ERROR)); | |
144 break; | 126 break; |
145 } | 127 } |
146 case Profile::CREATE_STATUS_CREATED: { | 128 case Profile::CREATE_STATUS_CREATED: { |
147 // Do nothing for an intermediate status. | 129 // Do nothing for an intermediate status. |
148 break; | 130 break; |
149 } | 131 } |
150 case Profile::CREATE_STATUS_INITIALIZED: { | 132 case Profile::CREATE_STATUS_INITIALIZED: { |
151 HandleProfileCreationSuccess(create_shortcut, desktop_type, | 133 HandleProfileCreationSuccess(create_shortcut, desktop_type, |
152 supervised_user_id, profile); | 134 supervised_user_id, profile); |
153 break; | 135 break; |
(...skipping 15 matching lines...) Expand all Loading... |
169 bool create_shortcut, | 151 bool create_shortcut, |
170 chrome::HostDesktopType desktop_type, | 152 chrome::HostDesktopType desktop_type, |
171 const std::string& supervised_user_id, | 153 const std::string& supervised_user_id, |
172 Profile* profile) { | 154 Profile* profile) { |
173 switch (profile_creation_type_) { | 155 switch (profile_creation_type_) { |
174 case NON_SUPERVISED_PROFILE_CREATION: { | 156 case NON_SUPERVISED_PROFILE_CREATION: { |
175 DCHECK(supervised_user_id.empty()); | 157 DCHECK(supervised_user_id.empty()); |
176 CreateShortcutAndShowSuccess(create_shortcut, desktop_type, profile); | 158 CreateShortcutAndShowSuccess(create_shortcut, desktop_type, profile); |
177 break; | 159 break; |
178 } | 160 } |
| 161 #if defined(ENABLE_MANAGED_USERS) |
179 case SUPERVISED_PROFILE_CREATION: | 162 case SUPERVISED_PROFILE_CREATION: |
180 case SUPERVISED_PROFILE_IMPORT: | 163 case SUPERVISED_PROFILE_IMPORT: |
181 RegisterSupervisedUser(create_shortcut, desktop_type, | 164 RegisterSupervisedUser(create_shortcut, desktop_type, |
182 supervised_user_id, profile); | 165 supervised_user_id, profile); |
183 break; | 166 break; |
| 167 #endif |
184 case NO_CREATION_IN_PROGRESS: | 168 case NO_CREATION_IN_PROGRESS: |
185 NOTREACHED(); | 169 NOTREACHED(); |
186 break; | 170 break; |
187 } | 171 } |
188 } | 172 } |
189 | 173 |
190 void CreateProfileHandler::RegisterSupervisedUser( | |
191 bool create_shortcut, | |
192 chrome::HostDesktopType desktop_type, | |
193 const std::string& supervised_user_id, | |
194 Profile* new_profile) { | |
195 DCHECK_EQ(profile_path_being_created_.value(), | |
196 new_profile->GetPath().value()); | |
197 | |
198 SupervisedUserService* supervised_user_service = | |
199 SupervisedUserServiceFactory::GetForProfile(new_profile); | |
200 | |
201 // Register the supervised user using the profile of the custodian. | |
202 supervised_user_registration_utility_ = | |
203 SupervisedUserRegistrationUtility::Create(Profile::FromWebUI(web_ui())); | |
204 supervised_user_service->RegisterAndInitSync( | |
205 supervised_user_registration_utility_.get(), | |
206 Profile::FromWebUI(web_ui()), | |
207 supervised_user_id, | |
208 base::Bind(&CreateProfileHandler::OnSupervisedUserRegistered, | |
209 weak_ptr_factory_.GetWeakPtr(), | |
210 create_shortcut, | |
211 desktop_type, | |
212 new_profile)); | |
213 } | |
214 | |
215 void CreateProfileHandler::OnSupervisedUserRegistered( | |
216 bool create_shortcut, | |
217 chrome::HostDesktopType desktop_type, | |
218 Profile* profile, | |
219 const GoogleServiceAuthError& error) { | |
220 GoogleServiceAuthError::State state = error.state(); | |
221 RecordSupervisedProfileCreationMetrics(state); | |
222 if (state == GoogleServiceAuthError::NONE) { | |
223 CreateShortcutAndShowSuccess(create_shortcut, desktop_type, profile); | |
224 return; | |
225 } | |
226 | |
227 base::string16 error_msg; | |
228 if (state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || | |
229 state == GoogleServiceAuthError::USER_NOT_SIGNED_UP || | |
230 state == GoogleServiceAuthError::ACCOUNT_DELETED || | |
231 state == GoogleServiceAuthError::ACCOUNT_DISABLED) { | |
232 error_msg = GetProfileCreationErrorMessage(SIGNIN_ERROR); | |
233 } else { | |
234 error_msg = GetProfileCreationErrorMessage(REMOTE_ERROR); | |
235 } | |
236 ShowProfileCreationError(profile, error_msg); | |
237 } | |
238 | |
239 void CreateProfileHandler::CreateShortcutAndShowSuccess( | 174 void CreateProfileHandler::CreateShortcutAndShowSuccess( |
240 bool create_shortcut, | 175 bool create_shortcut, |
241 chrome::HostDesktopType desktop_type, | 176 chrome::HostDesktopType desktop_type, |
242 Profile* profile) { | 177 Profile* profile) { |
243 if (create_shortcut) { | 178 if (create_shortcut) { |
244 ProfileShortcutManager* shortcut_manager = | 179 ProfileShortcutManager* shortcut_manager = |
245 g_browser_process->profile_manager()->profile_shortcut_manager(); | 180 g_browser_process->profile_manager()->profile_shortcut_manager(); |
246 | 181 |
247 if (shortcut_manager) | 182 if (shortcut_manager) |
248 shortcut_manager->CreateProfileShortcut(profile->GetPath()); | 183 shortcut_manager->CreateProfileShortcut(profile->GetPath()); |
249 } | 184 } |
250 | 185 |
251 DCHECK_EQ(profile_path_being_created_.value(), profile->GetPath().value()); | 186 DCHECK_EQ(profile_path_being_created_.value(), profile->GetPath().value()); |
252 profile_path_being_created_.clear(); | 187 profile_path_being_created_.clear(); |
253 DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); | 188 DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); |
254 base::DictionaryValue dict; | 189 base::DictionaryValue dict; |
255 dict.SetString("name", | 190 dict.SetString("name", |
256 profile->GetPrefs()->GetString(prefs::kProfileName)); | 191 profile->GetPrefs()->GetString(prefs::kProfileName)); |
257 dict.Set("filePath", base::CreateFilePathValue(profile->GetPath())); | 192 dict.Set("filePath", base::CreateFilePathValue(profile->GetPath())); |
| 193 #if defined(ENABLE_MANAGED_USERS) |
258 bool is_supervised = | 194 bool is_supervised = |
259 profile_creation_type_ == SUPERVISED_PROFILE_CREATION || | 195 profile_creation_type_ == SUPERVISED_PROFILE_CREATION || |
260 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT; | 196 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT; |
261 dict.SetBoolean("isSupervised", is_supervised); | 197 dict.SetBoolean("isSupervised", is_supervised); |
| 198 #endif |
262 web_ui()->CallJavascriptFunction( | 199 web_ui()->CallJavascriptFunction( |
263 GetJavascriptMethodName(PROFILE_CREATION_SUCCESS), dict); | 200 GetJavascriptMethodName(PROFILE_CREATION_SUCCESS), dict); |
264 | 201 |
265 // If the new profile is a supervised user, instead of opening a new window | 202 // If the new profile is a supervised user, instead of opening a new window |
266 // right away, a confirmation overlay will be shown by JS from the creation | 203 // right away, a confirmation overlay will be shown by JS from the creation |
267 // dialog. If we are importing an existing supervised profile or creating a | 204 // dialog. If we are importing an existing supervised profile or creating a |
268 // new non-supervised user profile we don't show any confirmation, so open | 205 // new non-supervised user profile we don't show any confirmation, so open |
269 // the new window now. | 206 // the new window now. |
270 if (profile_creation_type_ != SUPERVISED_PROFILE_CREATION) { | 207 bool should_open_new_window = true; |
| 208 #if defined(ENABLE_MANAGED_USERS) |
| 209 if (profile_creation_type_ == SUPERVISED_PROFILE_CREATION) |
| 210 should_open_new_window = false; |
| 211 #endif |
| 212 |
| 213 if (should_open_new_window) { |
271 // Opening the new window must be the last action, after all callbacks | 214 // Opening the new window must be the last action, after all callbacks |
272 // have been run, to give them a chance to initialize the profile. | 215 // have been run, to give them a chance to initialize the profile. |
273 helper::OpenNewWindowForProfile(desktop_type, | 216 helper::OpenNewWindowForProfile(desktop_type, |
274 profile, | 217 profile, |
275 Profile::CREATE_STATUS_INITIALIZED); | 218 Profile::CREATE_STATUS_INITIALIZED); |
276 } | 219 } |
277 profile_creation_type_ = NO_CREATION_IN_PROGRESS; | 220 profile_creation_type_ = NO_CREATION_IN_PROGRESS; |
278 } | 221 } |
279 | 222 |
280 void CreateProfileHandler::ShowProfileCreationError( | 223 void CreateProfileHandler::ShowProfileCreationError( |
281 Profile* profile, | 224 Profile* profile, |
282 const base::string16& error) { | 225 const base::string16& error) { |
283 DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); | 226 DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); |
284 profile_creation_type_ = NO_CREATION_IN_PROGRESS; | 227 profile_creation_type_ = NO_CREATION_IN_PROGRESS; |
285 profile_path_being_created_.clear(); | 228 profile_path_being_created_.clear(); |
286 web_ui()->CallJavascriptFunction( | 229 web_ui()->CallJavascriptFunction( |
287 GetJavascriptMethodName(PROFILE_CREATION_ERROR), | 230 GetJavascriptMethodName(PROFILE_CREATION_ERROR), |
288 base::StringValue(error)); | 231 base::StringValue(error)); |
289 // The ProfileManager calls us back with a NULL profile in some cases. | 232 // The ProfileManager calls us back with a NULL profile in some cases. |
290 if (profile) | 233 if (profile) |
291 helper::DeleteProfileAtPath(profile->GetPath(), web_ui()); | 234 helper::DeleteProfileAtPath(profile->GetPath(), web_ui()); |
292 } | 235 } |
293 | 236 |
294 void CreateProfileHandler::ShowProfileCreationWarning( | 237 void CreateProfileHandler::RecordProfileCreationMetrics( |
295 const base::string16& warning) { | 238 Profile::CreateStatus status) { |
296 DCHECK_EQ(SUPERVISED_PROFILE_CREATION, profile_creation_type_); | 239 UMA_HISTOGRAM_ENUMERATION("Profile.CreateResult", |
297 web_ui()->CallJavascriptFunction("BrowserOptions.showCreateProfileWarning", | 240 status, |
298 base::StringValue(warning)); | 241 Profile::MAX_CREATE_STATUS); |
| 242 UMA_HISTOGRAM_MEDIUM_TIMES( |
| 243 "Profile.CreateTimeNoTimeout", |
| 244 base::TimeTicks::Now() - profile_creation_start_time_); |
| 245 } |
| 246 |
| 247 base::string16 CreateProfileHandler::GetProfileCreationErrorMessageLocal() |
| 248 const { |
| 249 int message_id = IDS_PROFILES_CREATE_LOCAL_ERROR; |
| 250 #if defined(ENABLE_MANAGED_USERS) |
| 251 // Local errors can occur during supervised profile import. |
| 252 if (profile_creation_type_ == SUPERVISED_PROFILE_IMPORT) |
| 253 message_id = IDS_SUPERVISED_USER_IMPORT_LOCAL_ERROR; |
| 254 #endif |
| 255 return l10n_util::GetStringUTF16(message_id); |
| 256 } |
| 257 |
| 258 #if defined(ENABLE_MANAGED_USERS) |
| 259 base::string16 CreateProfileHandler::GetProfileCreationErrorMessageRemote() |
| 260 const { |
| 261 return l10n_util::GetStringUTF16( |
| 262 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? |
| 263 IDS_SUPERVISED_USER_IMPORT_REMOTE_ERROR : |
| 264 IDS_PROFILES_CREATE_REMOTE_ERROR); |
| 265 } |
| 266 |
| 267 base::string16 CreateProfileHandler::GetProfileCreationErrorMessageSignin() |
| 268 const { |
| 269 return l10n_util::GetStringUTF16( |
| 270 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? |
| 271 IDS_SUPERVISED_USER_IMPORT_SIGN_IN_ERROR : |
| 272 IDS_PROFILES_CREATE_SIGN_IN_ERROR); |
| 273 } |
| 274 #endif |
| 275 |
| 276 std::string CreateProfileHandler::GetJavascriptMethodName( |
| 277 ProfileCreationStatus status) const { |
| 278 switch (profile_creation_type_) { |
| 279 #if defined(ENABLE_MANAGED_USERS) |
| 280 case SUPERVISED_PROFILE_IMPORT: |
| 281 switch (status) { |
| 282 case PROFILE_CREATION_SUCCESS: |
| 283 return "BrowserOptions.showSupervisedUserImportSuccess"; |
| 284 case PROFILE_CREATION_ERROR: |
| 285 return "BrowserOptions.showSupervisedUserImportError"; |
| 286 } |
| 287 break; |
| 288 #endif |
| 289 default: |
| 290 switch (status) { |
| 291 case PROFILE_CREATION_SUCCESS: |
| 292 return "BrowserOptions.showCreateProfileSuccess"; |
| 293 case PROFILE_CREATION_ERROR: |
| 294 return "BrowserOptions.showCreateProfileError"; |
| 295 } |
| 296 break; |
| 297 } |
| 298 |
| 299 NOTREACHED(); |
| 300 return std::string(); |
| 301 } |
| 302 |
| 303 #if defined(ENABLE_MANAGED_USERS) |
| 304 bool CreateProfileHandler::ProcessSupervisedCreateProfileArgs( |
| 305 const base::ListValue* args, std::string* supervised_user_id) { |
| 306 bool supervised_user = false; |
| 307 if (args->GetSize() == 4) { |
| 308 bool success = args->GetBoolean(3, &supervised_user); |
| 309 DCHECK(success); |
| 310 |
| 311 success = args->GetString(4, supervised_user_id); |
| 312 DCHECK(success); |
| 313 } |
| 314 |
| 315 if (supervised_user) { |
| 316 if (!IsValidExistingSupervisedUserId(*supervised_user_id)) |
| 317 return false; |
| 318 |
| 319 profile_creation_type_ = SUPERVISED_PROFILE_IMPORT; |
| 320 if (supervised_user_id->empty()) { |
| 321 profile_creation_type_ = SUPERVISED_PROFILE_CREATION; |
| 322 *supervised_user_id = |
| 323 SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(); |
| 324 |
| 325 // If sync is not yet fully initialized, the creation may take extra time, |
| 326 // so show a message. Import doesn't wait for an acknowledgment, so it |
| 327 // won't have the same potential delay. |
| 328 ProfileSyncService* sync_service = |
| 329 ProfileSyncServiceFactory::GetInstance()->GetForProfile( |
| 330 Profile::FromWebUI(web_ui())); |
| 331 ProfileSyncService::SyncStatusSummary status = |
| 332 sync_service->QuerySyncStatusSummary(); |
| 333 if (status == ProfileSyncService::DATATYPES_NOT_INITIALIZED) { |
| 334 ShowProfileCreationWarning(l10n_util::GetStringUTF16( |
| 335 IDS_PROFILES_CREATE_SUPERVISED_JUST_SIGNED_IN)); |
| 336 } |
| 337 } |
| 338 } |
| 339 return true; |
299 } | 340 } |
300 | 341 |
301 void CreateProfileHandler::HandleCancelProfileCreation( | 342 void CreateProfileHandler::HandleCancelProfileCreation( |
302 const base::ListValue* args) { | 343 const base::ListValue* args) { |
303 CancelProfileRegistration(true); | 344 CancelProfileRegistration(true); |
304 } | 345 } |
305 | 346 |
| 347 // Non-supervised user creation cannot be canceled. (Creating a non-supervised |
| 348 // profile shouldn't take significant time, and it can easily be deleted |
| 349 // afterward.) |
306 void CreateProfileHandler::CancelProfileRegistration(bool user_initiated) { | 350 void CreateProfileHandler::CancelProfileRegistration(bool user_initiated) { |
307 if (profile_path_being_created_.empty()) | 351 if (profile_path_being_created_.empty()) |
308 return; | 352 return; |
309 | 353 |
310 ProfileManager* manager = g_browser_process->profile_manager(); | 354 ProfileManager* manager = g_browser_process->profile_manager(); |
311 Profile* new_profile = manager->GetProfileByPath(profile_path_being_created_); | 355 Profile* new_profile = manager->GetProfileByPath(profile_path_being_created_); |
312 if (!new_profile) | 356 if (!new_profile || !new_profile->IsSupervised()) |
313 return; | 357 return; |
314 | 358 |
315 // Non-supervised user creation cannot be canceled. (Creating a non-supervised | 359 DCHECK(supervised_user_registration_utility_.get()); |
316 // profile shouldn't take significant time, and it can easily be deleted | 360 supervised_user_registration_utility_.reset(); |
317 // afterward.) | |
318 if (!new_profile->IsSupervised()) | |
319 return; | |
320 | 361 |
321 if (user_initiated) { | 362 if (user_initiated) { |
322 UMA_HISTOGRAM_MEDIUM_TIMES( | 363 UMA_HISTOGRAM_MEDIUM_TIMES( |
323 "Profile.CreateTimeCanceledNoTimeout", | 364 "Profile.CreateTimeCanceledNoTimeout", |
324 base::TimeTicks::Now() - profile_creation_start_time_); | 365 base::TimeTicks::Now() - profile_creation_start_time_); |
325 RecordProfileCreationMetrics(Profile::CREATE_STATUS_CANCELED); | 366 RecordProfileCreationMetrics(Profile::CREATE_STATUS_CANCELED); |
326 } | 367 } |
327 | 368 |
328 DCHECK(supervised_user_registration_utility_.get()); | |
329 supervised_user_registration_utility_.reset(); | |
330 | |
331 DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); | 369 DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_); |
332 profile_creation_type_ = NO_CREATION_IN_PROGRESS; | 370 profile_creation_type_ = NO_CREATION_IN_PROGRESS; |
333 | 371 |
334 // Cancelling registration means the callback passed into | 372 // Cancelling registration means the callback passed into |
335 // RegisterAndInitSync() won't be called, so the cleanup must be done here. | 373 // RegisterAndInitSync() won't be called, so the cleanup must be done here. |
336 profile_path_being_created_.clear(); | 374 profile_path_being_created_.clear(); |
337 helper::DeleteProfileAtPath(new_profile->GetPath(), web_ui()); | 375 helper::DeleteProfileAtPath(new_profile->GetPath(), web_ui()); |
338 } | 376 } |
339 | 377 |
340 void CreateProfileHandler::RecordProfileCreationMetrics( | 378 void CreateProfileHandler::RegisterSupervisedUser( |
341 Profile::CreateStatus status) { | 379 bool create_shortcut, |
342 UMA_HISTOGRAM_ENUMERATION("Profile.CreateResult", | 380 chrome::HostDesktopType desktop_type, |
343 status, | 381 const std::string& supervised_user_id, |
344 Profile::MAX_CREATE_STATUS); | 382 Profile* new_profile) { |
345 UMA_HISTOGRAM_MEDIUM_TIMES( | 383 DCHECK_EQ(profile_path_being_created_.value(), |
346 "Profile.CreateTimeNoTimeout", | 384 new_profile->GetPath().value()); |
347 base::TimeTicks::Now() - profile_creation_start_time_); | 385 |
| 386 SupervisedUserService* supervised_user_service = |
| 387 SupervisedUserServiceFactory::GetForProfile(new_profile); |
| 388 |
| 389 // Register the supervised user using the profile of the custodian. |
| 390 supervised_user_registration_utility_ = |
| 391 SupervisedUserRegistrationUtility::Create(Profile::FromWebUI(web_ui())); |
| 392 supervised_user_service->RegisterAndInitSync( |
| 393 supervised_user_registration_utility_.get(), |
| 394 Profile::FromWebUI(web_ui()), |
| 395 supervised_user_id, |
| 396 base::Bind(&CreateProfileHandler::OnSupervisedUserRegistered, |
| 397 weak_ptr_factory_.GetWeakPtr(), |
| 398 create_shortcut, |
| 399 desktop_type, |
| 400 new_profile)); |
| 401 } |
| 402 |
| 403 void CreateProfileHandler::OnSupervisedUserRegistered( |
| 404 bool create_shortcut, |
| 405 chrome::HostDesktopType desktop_type, |
| 406 Profile* profile, |
| 407 const GoogleServiceAuthError& error) { |
| 408 GoogleServiceAuthError::State state = error.state(); |
| 409 RecordSupervisedProfileCreationMetrics(state); |
| 410 if (state == GoogleServiceAuthError::NONE) { |
| 411 CreateShortcutAndShowSuccess(create_shortcut, desktop_type, profile); |
| 412 return; |
| 413 } |
| 414 |
| 415 base::string16 error_msg; |
| 416 if (state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || |
| 417 state == GoogleServiceAuthError::USER_NOT_SIGNED_UP || |
| 418 state == GoogleServiceAuthError::ACCOUNT_DELETED || |
| 419 state == GoogleServiceAuthError::ACCOUNT_DISABLED) { |
| 420 error_msg = GetProfileCreationErrorMessageSignin(); |
| 421 } else { |
| 422 error_msg = GetProfileCreationErrorMessageRemote(); |
| 423 } |
| 424 ShowProfileCreationError(profile, error_msg); |
| 425 } |
| 426 |
| 427 void CreateProfileHandler::ShowProfileCreationWarning( |
| 428 const base::string16& warning) { |
| 429 DCHECK_EQ(SUPERVISED_PROFILE_CREATION, profile_creation_type_); |
| 430 web_ui()->CallJavascriptFunction("BrowserOptions.showCreateProfileWarning", |
| 431 base::StringValue(warning)); |
348 } | 432 } |
349 | 433 |
350 void CreateProfileHandler::RecordSupervisedProfileCreationMetrics( | 434 void CreateProfileHandler::RecordSupervisedProfileCreationMetrics( |
351 GoogleServiceAuthError::State error_state) { | 435 GoogleServiceAuthError::State error_state) { |
352 if (profile_creation_type_ == SUPERVISED_PROFILE_CREATION) { | 436 if (profile_creation_type_ == SUPERVISED_PROFILE_CREATION) { |
353 UMA_HISTOGRAM_ENUMERATION("Profile.SupervisedProfileCreateError", | 437 UMA_HISTOGRAM_ENUMERATION("Profile.SupervisedProfileCreateError", |
354 error_state, | 438 error_state, |
355 GoogleServiceAuthError::NUM_STATES); | 439 GoogleServiceAuthError::NUM_STATES); |
356 UMA_HISTOGRAM_MEDIUM_TIMES( | 440 UMA_HISTOGRAM_MEDIUM_TIMES( |
357 "Profile.SupervisedProfileTotalCreateTime", | 441 "Profile.SupervisedProfileTotalCreateTime", |
358 base::TimeTicks::Now() - profile_creation_start_time_); | 442 base::TimeTicks::Now() - profile_creation_start_time_); |
359 } else { | 443 } else { |
360 DCHECK_EQ(SUPERVISED_PROFILE_IMPORT, profile_creation_type_); | 444 DCHECK_EQ(SUPERVISED_PROFILE_IMPORT, profile_creation_type_); |
361 UMA_HISTOGRAM_ENUMERATION("Profile.SupervisedProfileImportError", | 445 UMA_HISTOGRAM_ENUMERATION("Profile.SupervisedProfileImportError", |
362 error_state, | 446 error_state, |
363 GoogleServiceAuthError::NUM_STATES); | 447 GoogleServiceAuthError::NUM_STATES); |
364 UMA_HISTOGRAM_MEDIUM_TIMES( | 448 UMA_HISTOGRAM_MEDIUM_TIMES( |
365 "Profile.SupervisedProfileTotalImportTime", | 449 "Profile.SupervisedProfileTotalImportTime", |
366 base::TimeTicks::Now() - profile_creation_start_time_); | 450 base::TimeTicks::Now() - profile_creation_start_time_); |
367 } | 451 } |
368 } | 452 } |
369 | 453 |
370 base::string16 CreateProfileHandler::GetProfileCreationErrorMessage( | |
371 ProfileCreationErrorType error) const { | |
372 int message_id = -1; | |
373 switch (error) { | |
374 case SIGNIN_ERROR: | |
375 message_id = | |
376 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? | |
377 IDS_SUPERVISED_USER_IMPORT_SIGN_IN_ERROR : | |
378 IDS_PROFILES_CREATE_SIGN_IN_ERROR; | |
379 break; | |
380 case REMOTE_ERROR: | |
381 message_id = | |
382 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? | |
383 IDS_SUPERVISED_USER_IMPORT_REMOTE_ERROR : | |
384 IDS_PROFILES_CREATE_REMOTE_ERROR; | |
385 break; | |
386 case LOCAL_ERROR: | |
387 message_id = | |
388 profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? | |
389 IDS_SUPERVISED_USER_IMPORT_LOCAL_ERROR : | |
390 IDS_PROFILES_CREATE_LOCAL_ERROR; | |
391 break; | |
392 } | |
393 | |
394 return l10n_util::GetStringUTF16(message_id); | |
395 } | |
396 | |
397 std::string CreateProfileHandler::GetJavascriptMethodName( | |
398 ProfileCreationStatus status) const { | |
399 switch (status) { | |
400 case PROFILE_CREATION_SUCCESS: | |
401 return profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? | |
402 "BrowserOptions.showSupervisedUserImportSuccess" : | |
403 "BrowserOptions.showCreateProfileSuccess"; | |
404 case PROFILE_CREATION_ERROR: | |
405 return profile_creation_type_ == SUPERVISED_PROFILE_IMPORT ? | |
406 "BrowserOptions.showSupervisedUserImportError" : | |
407 "BrowserOptions.showCreateProfileError"; | |
408 } | |
409 | |
410 NOTREACHED(); | |
411 return std::string(); | |
412 } | |
413 | |
414 bool CreateProfileHandler::IsValidExistingSupervisedUserId( | 454 bool CreateProfileHandler::IsValidExistingSupervisedUserId( |
415 const std::string& existing_supervised_user_id) const { | 455 const std::string& existing_supervised_user_id) const { |
416 if (existing_supervised_user_id.empty()) | 456 if (existing_supervised_user_id.empty()) |
417 return true; | 457 return true; |
418 | 458 |
419 Profile* profile = Profile::FromWebUI(web_ui()); | 459 Profile* profile = Profile::FromWebUI(web_ui()); |
420 const base::DictionaryValue* dict = | 460 const base::DictionaryValue* dict = |
421 SupervisedUserSyncServiceFactory::GetForProfile(profile)-> | 461 SupervisedUserSyncServiceFactory::GetForProfile(profile)-> |
422 GetSupervisedUsers(); | 462 GetSupervisedUsers(); |
423 if (!dict->HasKey(existing_supervised_user_id)) | 463 if (!dict->HasKey(existing_supervised_user_id)) |
424 return false; | 464 return false; |
425 | 465 |
426 // Check if this supervised user already exists on this machine. | 466 // Check if this supervised user already exists on this machine. |
427 const ProfileInfoCache& cache = | 467 const ProfileInfoCache& cache = |
428 g_browser_process->profile_manager()->GetProfileInfoCache(); | 468 g_browser_process->profile_manager()->GetProfileInfoCache(); |
429 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 469 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
430 if (existing_supervised_user_id == | 470 if (existing_supervised_user_id == |
431 cache.GetSupervisedUserIdOfProfileAtIndex(i)) | 471 cache.GetSupervisedUserIdOfProfileAtIndex(i)) |
432 return false; | 472 return false; |
433 } | 473 } |
434 return true; | 474 return true; |
435 } | 475 } |
| 476 #endif |
436 | 477 |
437 } // namespace options | 478 } // namespace options |
OLD | NEW |