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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/signin/signin_names_io_thread.h" 6 7 #include "base/logging.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/profiles/profile_info_cache.h" 12 #include "chrome/browser/profiles/profile_manager.h" 13 #include "chrome/browser/signin/signin_manager.h" 14 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/notification_service.h" 16 17 SigninNamesOnIOThread::SigninNamesOnIOThread() { 18 CheckOnUIThread(); 19 20 // We want to register for all profiles, not just for the current profile. 21 registrar_.reset(new content::NotificationRegistrar); 22 registrar_->Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 23 content::NotificationService::AllSources()); 24 registrar_->Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 25 content::NotificationService::AllSources()); 26 27 // Get list of profiles and record the email addresses of any connected 28 // accounts. 29 if (g_browser_process) { 30 ProfileManager* manager = g_browser_process->profile_manager(); 31 if (manager) { 32 const ProfileInfoCache& cache = manager->GetProfileInfoCache(); 33 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { 34 base::string16 email = cache.GetUserNameOfProfileAtIndex(i); 35 if (!email.empty()) 36 emails_.insert(email); 37 } 38 } 39 } 40 } 41 42 SigninNamesOnIOThread::~SigninNamesOnIOThread() { 43 CheckOnIOThread(); 44 DCHECK(!registrar_) << "Must call ReleaseResourcesOnUIThread() first"; 45 } 46 47 const SigninNamesOnIOThread::EmailSet& 48 SigninNamesOnIOThread::GetEmails() const { 49 CheckOnIOThread(); 50 return emails_; 51 } 52 53 void SigninNamesOnIOThread::ReleaseResourcesOnUIThread() { 54 CheckOnUIThread(); 55 registrar_.reset(); 56 } 57 58 void SigninNamesOnIOThread::Observe( 59 int type, 60 const content::NotificationSource& source, 61 const content::NotificationDetails& details) { 62 CheckOnUIThread(); 63 64 switch (type) { 65 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { 66 const GoogleServiceSigninSuccessDetails* signin_details = 67 content::Details<GoogleServiceSigninSuccessDetails>(details).ptr(); 68 PostTaskToIOThread(type, UTF8ToUTF16(signin_details->username)); 69 break; 70 } 71 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: { 72 const GoogleServiceSignoutDetails* signout_details = 73 content::Details<GoogleServiceSignoutDetails>(details).ptr(); 74 PostTaskToIOThread(type, UTF8ToUTF16(signout_details->username)); 75 break; 76 } 77 default: 78 NOTREACHED() << "Unexpected type=" << type; 79 } 80 } 81 82 void SigninNamesOnIOThread::CheckOnIOThread() const { 83 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 84 } 85 86 void SigninNamesOnIOThread::CheckOnUIThread() const { 87 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 88 } 89 90 void SigninNamesOnIOThread::PostTaskToIOThread( 91 int type, 92 const base::string16& email) { 93 if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) { 94 UpdateOnIOThread(type, email); 95 } else { 96 bool may_run = content::BrowserThread::PostTask( 97 content::BrowserThread::IO, 98 FROM_HERE, 99 base::Bind(&SigninNamesOnIOThread::UpdateOnIOThread, 100 base::Unretained(this), type, email)); 101 DCHECK(may_run); 102 } 103 } 104 105 void SigninNamesOnIOThread::UpdateOnIOThread( 106 int type, 107 const base::string16& email) { 108 CheckOnIOThread(); 109 if (type == chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL) { 110 emails_.insert(email); 111 } else { 112 emails_.erase(email); 113 } 114 } 115