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/signin/user_manager_screen_handler.h" | 5 #include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 new UserManagerScreenHandler::ProfileUpdateObserver( | 290 new UserManagerScreenHandler::ProfileUpdateObserver( |
291 g_browser_process->profile_manager(), this)); | 291 g_browser_process->profile_manager(), this)); |
292 } | 292 } |
293 | 293 |
294 UserManagerScreenHandler::~UserManagerScreenHandler() { | 294 UserManagerScreenHandler::~UserManagerScreenHandler() { |
295 proximity_auth::ScreenlockBridge::Get()->SetLockHandler(NULL); | 295 proximity_auth::ScreenlockBridge::Get()->SetLockHandler(NULL); |
296 } | 296 } |
297 | 297 |
298 void UserManagerScreenHandler::ShowBannerMessage( | 298 void UserManagerScreenHandler::ShowBannerMessage( |
299 const base::string16& message) { | 299 const base::string16& message) { |
300 web_ui()->CallJavascriptFunction( | 300 web_ui()->CallJavascriptFunctionUnsafe( |
301 "login.AccountPickerScreen.showBannerMessage", | 301 "login.AccountPickerScreen.showBannerMessage", |
302 base::StringValue(message)); | 302 base::StringValue(message)); |
303 } | 303 } |
304 | 304 |
305 void UserManagerScreenHandler::ShowUserPodCustomIcon( | 305 void UserManagerScreenHandler::ShowUserPodCustomIcon( |
306 const AccountId& account_id, | 306 const AccountId& account_id, |
307 const proximity_auth::ScreenlockBridge::UserPodCustomIconOptions& | 307 const proximity_auth::ScreenlockBridge::UserPodCustomIconOptions& |
308 icon_options) { | 308 icon_options) { |
309 std::unique_ptr<base::DictionaryValue> icon = | 309 std::unique_ptr<base::DictionaryValue> icon = |
310 icon_options.ToDictionaryValue(); | 310 icon_options.ToDictionaryValue(); |
311 if (!icon || icon->empty()) | 311 if (!icon || icon->empty()) |
312 return; | 312 return; |
313 web_ui()->CallJavascriptFunction( | 313 web_ui()->CallJavascriptFunctionUnsafe( |
314 "login.AccountPickerScreen.showUserPodCustomIcon", | 314 "login.AccountPickerScreen.showUserPodCustomIcon", |
315 base::StringValue(account_id.GetUserEmail()), *icon); | 315 base::StringValue(account_id.GetUserEmail()), *icon); |
316 } | 316 } |
317 | 317 |
318 void UserManagerScreenHandler::HideUserPodCustomIcon( | 318 void UserManagerScreenHandler::HideUserPodCustomIcon( |
319 const AccountId& account_id) { | 319 const AccountId& account_id) { |
320 web_ui()->CallJavascriptFunction( | 320 web_ui()->CallJavascriptFunctionUnsafe( |
321 "login.AccountPickerScreen.hideUserPodCustomIcon", | 321 "login.AccountPickerScreen.hideUserPodCustomIcon", |
322 base::StringValue(account_id.GetUserEmail())); | 322 base::StringValue(account_id.GetUserEmail())); |
323 } | 323 } |
324 | 324 |
325 void UserManagerScreenHandler::EnableInput() { | 325 void UserManagerScreenHandler::EnableInput() { |
326 // Nothing here because UI is not disabled when starting to authenticate. | 326 // Nothing here because UI is not disabled when starting to authenticate. |
327 } | 327 } |
328 | 328 |
329 void UserManagerScreenHandler::SetAuthType( | 329 void UserManagerScreenHandler::SetAuthType( |
330 const AccountId& account_id, | 330 const AccountId& account_id, |
331 proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type, | 331 proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type, |
332 const base::string16& auth_value) { | 332 const base::string16& auth_value) { |
333 if (GetAuthType(account_id) == | 333 if (GetAuthType(account_id) == |
334 proximity_auth::ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD) | 334 proximity_auth::ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD) |
335 return; | 335 return; |
336 | 336 |
337 user_auth_type_map_[account_id.GetUserEmail()] = auth_type; | 337 user_auth_type_map_[account_id.GetUserEmail()] = auth_type; |
338 web_ui()->CallJavascriptFunction("login.AccountPickerScreen.setAuthType", | 338 web_ui()->CallJavascriptFunctionUnsafe( |
339 base::StringValue(account_id.GetUserEmail()), | 339 "login.AccountPickerScreen.setAuthType", |
340 base::FundamentalValue(auth_type), | 340 base::StringValue(account_id.GetUserEmail()), |
341 base::StringValue(auth_value)); | 341 base::FundamentalValue(auth_type), base::StringValue(auth_value)); |
342 } | 342 } |
343 | 343 |
344 proximity_auth::ScreenlockBridge::LockHandler::AuthType | 344 proximity_auth::ScreenlockBridge::LockHandler::AuthType |
345 UserManagerScreenHandler::GetAuthType(const AccountId& account_id) const { | 345 UserManagerScreenHandler::GetAuthType(const AccountId& account_id) const { |
346 const auto it = user_auth_type_map_.find(account_id.GetUserEmail()); | 346 const auto it = user_auth_type_map_.find(account_id.GetUserEmail()); |
347 if (it == user_auth_type_map_.end()) | 347 if (it == user_auth_type_map_.end()) |
348 return proximity_auth::ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; | 348 return proximity_auth::ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; |
349 return it->second; | 349 return it->second; |
350 } | 350 } |
351 | 351 |
(...skipping 15 matching lines...) Expand all Loading... |
367 const std::string& secret, | 367 const std::string& secret, |
368 const std::string& key_label) { | 368 const std::string& key_label) { |
369 NOTREACHED(); | 369 NOTREACHED(); |
370 } | 370 } |
371 | 371 |
372 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) { | 372 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) { |
373 // If the URL has a hash parameter, store it for later. | 373 // If the URL has a hash parameter, store it for later. |
374 args->GetString(0, &url_hash_); | 374 args->GetString(0, &url_hash_); |
375 | 375 |
376 SendUserList(); | 376 SendUserList(); |
377 web_ui()->CallJavascriptFunction("cr.ui.UserManager.showUserManagerScreen", | 377 web_ui()->CallJavascriptFunctionUnsafe( |
| 378 "cr.ui.UserManager.showUserManagerScreen", |
378 base::FundamentalValue(IsGuestModeEnabled()), | 379 base::FundamentalValue(IsGuestModeEnabled()), |
379 base::FundamentalValue(IsAddPersonEnabled())); | 380 base::FundamentalValue(IsAddPersonEnabled())); |
380 | 381 |
381 proximity_auth::ScreenlockBridge::Get()->SetLockHandler(this); | 382 proximity_auth::ScreenlockBridge::Get()->SetLockHandler(this); |
382 } | 383 } |
383 | 384 |
384 void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) { | 385 void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) { |
385 if (!IsAddPersonEnabled()) { | 386 if (!IsAddPersonEnabled()) { |
386 // The 'Add User' UI should not be showing. | 387 // The 'Add User' UI should not be showing. |
387 NOTREACHED(); | 388 NOTREACHED(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 | 462 |
462 base::FilePath profile_path; | 463 base::FilePath profile_path; |
463 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path)) { | 464 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path)) { |
464 NOTREACHED(); | 465 NOTREACHED(); |
465 return; | 466 return; |
466 } | 467 } |
467 | 468 |
468 DCHECK(profiles::IsMultipleProfilesEnabled()); | 469 DCHECK(profiles::IsMultipleProfilesEnabled()); |
469 | 470 |
470 if (profiles::AreAllProfilesLocked()) { | 471 if (profiles::AreAllProfilesLocked()) { |
471 web_ui()->CallJavascriptFunction( | 472 web_ui()->CallJavascriptFunctionUnsafe( |
472 "cr.webUIListenerCallback", | 473 "cr.webUIListenerCallback", base::StringValue("show-error-dialog"), |
473 base::StringValue("show-error-dialog"), | |
474 base::StringValue(l10n_util::GetStringUTF8( | 474 base::StringValue(l10n_util::GetStringUTF8( |
475 IDS_USER_MANAGER_REMOVE_PROFILE_PROFILES_LOCKED_ERROR))); | 475 IDS_USER_MANAGER_REMOVE_PROFILE_PROFILES_LOCKED_ERROR))); |
476 return; | 476 return; |
477 } | 477 } |
478 | 478 |
479 // The callback is run if the only profile has been deleted, and a new | 479 // The callback is run if the only profile has been deleted, and a new |
480 // profile has been created to replace it. | 480 // profile has been created to replace it. |
481 webui::DeleteProfileAtPath(profile_path, | 481 webui::DeleteProfileAtPath(profile_path, |
482 web_ui(), | 482 web_ui(), |
483 ProfileMetrics::DELETE_PROFILE_USER_MANAGER); | 483 ProfileMetrics::DELETE_PROFILE_USER_MANAGER); |
(...skipping 11 matching lines...) Expand all Loading... |
495 } | 495 } |
496 } | 496 } |
497 | 497 |
498 void UserManagerScreenHandler::HandleAreAllProfilesLocked( | 498 void UserManagerScreenHandler::HandleAreAllProfilesLocked( |
499 const base::ListValue* args) { | 499 const base::ListValue* args) { |
500 std::string webui_callback_id; | 500 std::string webui_callback_id; |
501 CHECK_EQ(1U, args->GetSize()); | 501 CHECK_EQ(1U, args->GetSize()); |
502 bool success = args->GetString(0, &webui_callback_id); | 502 bool success = args->GetString(0, &webui_callback_id); |
503 DCHECK(success); | 503 DCHECK(success); |
504 | 504 |
505 web_ui()->CallJavascriptFunction( | 505 web_ui()->CallJavascriptFunctionUnsafe( |
506 "cr.webUIResponse", | 506 "cr.webUIResponse", base::StringValue(webui_callback_id), |
507 base::StringValue(webui_callback_id), | |
508 base::FundamentalValue(true), | 507 base::FundamentalValue(true), |
509 base::FundamentalValue(profiles::AreAllProfilesLocked())); | 508 base::FundamentalValue(profiles::AreAllProfilesLocked())); |
510 } | 509 } |
511 | 510 |
512 void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) { | 511 void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) { |
513 const base::Value* profile_path_value = NULL; | 512 const base::Value* profile_path_value = NULL; |
514 if (!args->Get(0, &profile_path_value)) | 513 if (!args->Get(0, &profile_path_value)) |
515 return; | 514 return; |
516 | 515 |
517 base::FilePath profile_path; | 516 base::FilePath profile_path; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 profile_path); | 592 profile_path); |
594 bool stats_success = true; | 593 bool stats_success = true; |
595 for (const auto& item : stats) { | 594 for (const auto& item : stats) { |
596 std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); | 595 std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); |
597 stat->SetIntegerWithoutPathExpansion("count", item.count); | 596 stat->SetIntegerWithoutPathExpansion("count", item.count); |
598 stat->SetBooleanWithoutPathExpansion("success", item.success); | 597 stat->SetBooleanWithoutPathExpansion("success", item.success); |
599 return_value.SetWithoutPathExpansion(item.category, std::move(stat)); | 598 return_value.SetWithoutPathExpansion(item.category, std::move(stat)); |
600 stats_success &= item.success; | 599 stats_success &= item.success; |
601 } | 600 } |
602 if (stats_success) { | 601 if (stats_success) { |
603 web_ui()->CallJavascriptFunction("updateRemoveWarningDialog", | 602 web_ui()->CallJavascriptFunctionUnsafe( |
604 base::StringValue(profile_path.value()), | 603 "updateRemoveWarningDialog", base::StringValue(profile_path.value()), |
605 return_value); | 604 return_value); |
606 return; | 605 return; |
607 } | 606 } |
608 } | 607 } |
609 | 608 |
610 ProfileStatisticsFactory::GetForProfile(profile)->GatherStatistics( | 609 ProfileStatisticsFactory::GetForProfile(profile)->GatherStatistics( |
611 base::Bind( | 610 base::Bind( |
612 &UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback, | 611 &UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback, |
613 weak_ptr_factory_.GetWeakPtr(), profile_path)); | 612 weak_ptr_factory_.GetWeakPtr(), profile_path)); |
614 } | 613 } |
615 | 614 |
616 void UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback( | 615 void UserManagerScreenHandler::RemoveUserDialogLoadStatsCallback( |
617 base::FilePath profile_path, | 616 base::FilePath profile_path, |
618 profiles::ProfileCategoryStats result) { | 617 profiles::ProfileCategoryStats result) { |
619 // Copy result into return_value. | 618 // Copy result into return_value. |
620 base::DictionaryValue return_value; | 619 base::DictionaryValue return_value; |
621 for (const auto& item : result) { | 620 for (const auto& item : result) { |
622 std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); | 621 std::unique_ptr<base::DictionaryValue> stat(new base::DictionaryValue); |
623 stat->SetIntegerWithoutPathExpansion("count", item.count); | 622 stat->SetIntegerWithoutPathExpansion("count", item.count); |
624 stat->SetBooleanWithoutPathExpansion("success", item.success); | 623 stat->SetBooleanWithoutPathExpansion("success", item.success); |
625 return_value.SetWithoutPathExpansion(item.category, std::move(stat)); | 624 return_value.SetWithoutPathExpansion(item.category, std::move(stat)); |
626 } | 625 } |
627 web_ui()->CallJavascriptFunction("updateRemoveWarningDialog", | 626 web_ui()->CallJavascriptFunctionUnsafe( |
628 base::StringValue(profile_path.value()), | 627 "updateRemoveWarningDialog", base::StringValue(profile_path.value()), |
629 return_value); | 628 return_value); |
630 } | 629 } |
631 | 630 |
632 void UserManagerScreenHandler::HandleGetRemoveWarningDialogMessage( | 631 void UserManagerScreenHandler::HandleGetRemoveWarningDialogMessage( |
633 const base::ListValue* args) { | 632 const base::ListValue* args) { |
634 const base::DictionaryValue* arg; | 633 const base::DictionaryValue* arg; |
635 if (!args->GetDictionary(0, &arg)) | 634 if (!args->GetDictionary(0, &arg)) |
636 return; | 635 return; |
637 | 636 |
638 std::string profile_path(""); | 637 std::string profile_path(""); |
639 bool is_synced_user = false; | 638 bool is_synced_user = false; |
(...skipping 10 matching lines...) Expand all Loading... |
650 | 649 |
651 int message_id = is_synced_user ? | 650 int message_id = is_synced_user ? |
652 (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC_WITH_ERRORS : | 651 (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC_WITH_ERRORS : |
653 IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC) : | 652 IDS_LOGIN_POD_USER_REMOVE_WARNING_SYNC) : |
654 (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC_WITH_ERRORS : | 653 (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC_WITH_ERRORS : |
655 IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC); | 654 IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC); |
656 | 655 |
657 base::StringValue message = base::StringValue( | 656 base::StringValue message = base::StringValue( |
658 l10n_util::GetPluralStringFUTF16(message_id, total_count)); | 657 l10n_util::GetPluralStringFUTF16(message_id, total_count)); |
659 | 658 |
660 web_ui()->CallJavascriptFunction("updateRemoveWarningDialogSetMessage", | 659 web_ui()->CallJavascriptFunctionUnsafe( |
661 base::StringValue(profile_path), | 660 "updateRemoveWarningDialogSetMessage", base::StringValue(profile_path), |
662 message, | 661 message, base::FundamentalValue(total_count)); |
663 base::FundamentalValue(total_count)); | |
664 } | 662 } |
665 | 663 |
666 void UserManagerScreenHandler::OnGetTokenInfoResponse( | 664 void UserManagerScreenHandler::OnGetTokenInfoResponse( |
667 std::unique_ptr<base::DictionaryValue> token_info) { | 665 std::unique_ptr<base::DictionaryValue> token_info) { |
668 // Password is unchanged so user just mistyped it. Ask again. | 666 // Password is unchanged so user just mistyped it. Ask again. |
669 ReportAuthenticationResult(false, ProfileMetrics::AUTH_FAILED); | 667 ReportAuthenticationResult(false, ProfileMetrics::AUTH_FAILED); |
670 } | 668 } |
671 | 669 |
672 void UserManagerScreenHandler::OnOAuthError() { | 670 void UserManagerScreenHandler::OnOAuthError() { |
673 // Password has changed. Go through online signin flow. | 671 // Password has changed. Go through online signin flow. |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 | 920 |
923 // GetProfileByPath returns a pointer if the profile is fully loaded, NULL | 921 // GetProfileByPath returns a pointer if the profile is fully loaded, NULL |
924 // otherwise. | 922 // otherwise. |
925 Profile* profile = | 923 Profile* profile = |
926 g_browser_process->profile_manager()->GetProfileByPath(profile_path); | 924 g_browser_process->profile_manager()->GetProfileByPath(profile_path); |
927 profile_value->SetBoolean(kKeyIsProfileLoaded, profile != nullptr); | 925 profile_value->SetBoolean(kKeyIsProfileLoaded, profile != nullptr); |
928 | 926 |
929 users_list.Append(profile_value); | 927 users_list.Append(profile_value); |
930 } | 928 } |
931 | 929 |
932 web_ui()->CallJavascriptFunction("login.AccountPickerScreen.loadUsers", | 930 web_ui()->CallJavascriptFunctionUnsafe( |
933 users_list, base::FundamentalValue(IsGuestModeEnabled())); | 931 "login.AccountPickerScreen.loadUsers", users_list, |
| 932 base::FundamentalValue(IsGuestModeEnabled())); |
934 | 933 |
935 // This is the latest C++ code we have in the flow to show the UserManager. | 934 // This is the latest C++ code we have in the flow to show the UserManager. |
936 // This may be invoked more than once per UserManager lifetime; the | 935 // This may be invoked more than once per UserManager lifetime; the |
937 // UserManager will ensure all relevant logging only happens once. | 936 // UserManager will ensure all relevant logging only happens once. |
938 UserManager::OnUserManagerShown(); | 937 UserManager::OnUserManagerShown(); |
939 } | 938 } |
940 | 939 |
941 void UserManagerScreenHandler::ReportAuthenticationResult( | 940 void UserManagerScreenHandler::ReportAuthenticationResult( |
942 bool success, | 941 bool success, |
943 ProfileMetrics::ProfileAuth auth) { | 942 ProfileMetrics::ProfileAuth auth) { |
944 ProfileMetrics::LogProfileAuthResult(auth); | 943 ProfileMetrics::LogProfileAuthResult(auth); |
945 email_address_.clear(); | 944 email_address_.clear(); |
946 | 945 |
947 if (success) { | 946 if (success) { |
948 profiles::SwitchToProfile( | 947 profiles::SwitchToProfile( |
949 authenticating_profile_path_, true, | 948 authenticating_profile_path_, true, |
950 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete, | 949 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete, |
951 weak_ptr_factory_.GetWeakPtr()), | 950 weak_ptr_factory_.GetWeakPtr()), |
952 ProfileMetrics::SWITCH_PROFILE_UNLOCK); | 951 ProfileMetrics::SWITCH_PROFILE_UNLOCK); |
953 } else { | 952 } else { |
954 web_ui()->CallJavascriptFunction( | 953 web_ui()->CallJavascriptFunctionUnsafe( |
955 "cr.ui.UserManager.showSignInError", | 954 "cr.ui.UserManager.showSignInError", base::FundamentalValue(0), |
956 base::FundamentalValue(0), | |
957 base::StringValue(l10n_util::GetStringUTF8( | 955 base::StringValue(l10n_util::GetStringUTF8( |
958 auth == ProfileMetrics::AUTH_FAILED_OFFLINE ? | 956 auth == ProfileMetrics::AUTH_FAILED_OFFLINE |
959 IDS_LOGIN_ERROR_AUTHENTICATING_OFFLINE : | 957 ? IDS_LOGIN_ERROR_AUTHENTICATING_OFFLINE |
960 IDS_LOGIN_ERROR_AUTHENTICATING)), | 958 : IDS_LOGIN_ERROR_AUTHENTICATING)), |
961 base::StringValue(""), | 959 base::StringValue(""), base::FundamentalValue(0)); |
962 base::FundamentalValue(0)); | |
963 } | 960 } |
964 } | 961 } |
965 | 962 |
966 void UserManagerScreenHandler::OnBrowserWindowReady(Browser* browser) { | 963 void UserManagerScreenHandler::OnBrowserWindowReady(Browser* browser) { |
967 DCHECK(browser); | 964 DCHECK(browser); |
968 DCHECK(browser->window()); | 965 DCHECK(browser->window()); |
969 | 966 |
970 // Unlock the profile after browser opens so startup can read the lock bit. | 967 // Unlock the profile after browser opens so startup can read the lock bit. |
971 // Any necessary authentication must have been successful to reach this point. | 968 // Any necessary authentication must have been successful to reach this point. |
972 if (!browser->profile()->IsGuestSession()) { | 969 if (!browser->profile()->IsGuestSession()) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 Profile* profile, Profile::CreateStatus profile_create_status) { | 1012 Profile* profile, Profile::CreateStatus profile_create_status) { |
1016 Browser* browser = chrome::FindAnyBrowser(profile, false); | 1013 Browser* browser = chrome::FindAnyBrowser(profile, false); |
1017 if (browser && browser->window()) { | 1014 if (browser && browser->window()) { |
1018 OnBrowserWindowReady(browser); | 1015 OnBrowserWindowReady(browser); |
1019 } else { | 1016 } else { |
1020 registrar_.Add(this, | 1017 registrar_.Add(this, |
1021 chrome::NOTIFICATION_BROWSER_WINDOW_READY, | 1018 chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
1022 content::NotificationService::AllSources()); | 1019 content::NotificationService::AllSources()); |
1023 } | 1020 } |
1024 } | 1021 } |
OLD | NEW |