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 "components/signin/core/browser/signin_manager.h"
14#include "content/public/browser/browser_thread.h"
15
16SigninNamesOnIOThread::SigninNamesOnIOThread() : resources_released_(false) {
17  CheckOnUIThread();
18
19  SigninManagerFactory::GetInstance()->AddObserver(this);
20
21  // Get list of profiles and record the email addresses of any connected
22  // accounts.
23  if (g_browser_process) {
24    ProfileManager* manager = g_browser_process->profile_manager();
25    if (manager) {
26      const ProfileInfoCache& cache = manager->GetProfileInfoCache();
27      for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
28        base::string16 email = cache.GetUserNameOfProfileAtIndex(i);
29        if (!email.empty())
30          emails_.insert(email);
31      }
32    }
33  }
34}
35
36SigninNamesOnIOThread::~SigninNamesOnIOThread() {
37  CheckOnIOThread();
38  DCHECK(resources_released_) << "Must call ReleaseResourcesOnUIThread() first";
39  DCHECK(!observed_managers_.size())
40      << "Shouldn't be observing any SigninManagers";
41}
42
43const SigninNamesOnIOThread::EmailSet&
44    SigninNamesOnIOThread::GetEmails() const {
45  CheckOnIOThread();
46  return emails_;
47}
48
49void SigninNamesOnIOThread::ReleaseResourcesOnUIThread() {
50  CheckOnUIThread();
51  DCHECK(!resources_released_);
52  SigninManagerFactory::GetInstance()->RemoveObserver(this);
53
54  for (std::set<SigninManagerBase*>::iterator i = observed_managers_.begin();
55       i != observed_managers_.end();
56       ++i) {
57    (*i)->RemoveObserver(this);
58  }
59  observed_managers_.clear();
60
61  resources_released_ = true;
62}
63
64void SigninNamesOnIOThread::SigninManagerCreated(SigninManagerBase* manager) {
65  manager->AddObserver(this);
66  observed_managers_.insert(manager);
67}
68
69void SigninNamesOnIOThread::SigninManagerShutdown(SigninManagerBase* manager) {
70  manager->RemoveObserver(this);
71  observed_managers_.erase(manager);
72}
73
74void SigninNamesOnIOThread::GoogleSigninSucceeded(const std::string& account_id,
75                                                  const std::string& username,
76                                                  const std::string& password) {
77  PostTaskToIOThread(true, base::UTF8ToUTF16(username));
78}
79
80void SigninNamesOnIOThread::GoogleSignedOut(const std::string& account_id,
81                                            const std::string& username) {
82  PostTaskToIOThread(false, base::UTF8ToUTF16(username));
83}
84
85void SigninNamesOnIOThread::CheckOnIOThread() const {
86  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
87}
88
89void SigninNamesOnIOThread::CheckOnUIThread() const {
90  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
91}
92
93void SigninNamesOnIOThread::PostTaskToIOThread(bool add,
94                                               const base::string16& email) {
95  if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
96    UpdateOnIOThread(add, email);
97  } else {
98    bool may_run = content::BrowserThread::PostTask(
99        content::BrowserThread::IO,
100        FROM_HERE,
101        base::Bind(&SigninNamesOnIOThread::UpdateOnIOThread,
102                   base::Unretained(this),
103                   add,
104                   email));
105    DCHECK(may_run);
106  }
107}
108
109void SigninNamesOnIOThread::UpdateOnIOThread(bool add,
110                                             const base::string16& email) {
111  CheckOnIOThread();
112  if (add) {
113    emails_.insert(email);
114  } else {
115    emails_.erase(email);
116  }
117}
118