Home | History | Annotate | Download | only in signin
      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         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 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 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