• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "components/signin/core/browser/signin_error_controller.h"
6 
7 namespace {
8 
9 typedef std::set<const SigninErrorController::AuthStatusProvider*>
10     AuthStatusProviderSet;
11 
12 }  // namespace
13 
AuthStatusProvider()14 SigninErrorController::AuthStatusProvider::AuthStatusProvider() {
15 }
16 
~AuthStatusProvider()17 SigninErrorController::AuthStatusProvider::~AuthStatusProvider() {
18 }
19 
SigninErrorController()20 SigninErrorController::SigninErrorController()
21     : auth_error_(GoogleServiceAuthError::AuthErrorNone()) {
22 }
23 
~SigninErrorController()24 SigninErrorController::~SigninErrorController() {
25   DCHECK(provider_set_.empty())
26       << "All AuthStatusProviders should be unregistered before"
27       << " SigninErrorController::Shutdown() is called";
28 }
29 
AddProvider(const AuthStatusProvider * provider)30 void SigninErrorController::AddProvider(const AuthStatusProvider* provider) {
31   DCHECK(provider_set_.find(provider) == provider_set_.end())
32       << "Adding same AuthStatusProvider multiple times";
33   provider_set_.insert(provider);
34   AuthStatusChanged();
35 }
36 
RemoveProvider(const AuthStatusProvider * provider)37 void SigninErrorController::RemoveProvider(const AuthStatusProvider* provider) {
38   AuthStatusProviderSet::iterator iter = provider_set_.find(provider);
39   DCHECK(iter != provider_set_.end())
40       << "Removing provider that was never added";
41   provider_set_.erase(iter);
42   AuthStatusChanged();
43 }
44 
AuthStatusChanged()45 void SigninErrorController::AuthStatusChanged() {
46   GoogleServiceAuthError::State prev_state = auth_error_.state();
47   std::string prev_account_id = error_account_id_;
48   bool error_changed = false;
49 
50   // Find an error among the status providers. If |auth_error_| has an
51   // actionable error state and some provider exposes a similar error and
52   // account id, use that error. Otherwise, just take the first actionable
53   // error we find.
54   for (AuthStatusProviderSet::const_iterator it = provider_set_.begin();
55        it != provider_set_.end(); ++it) {
56     GoogleServiceAuthError error = (*it)->GetAuthStatus();
57 
58     // Ignore the states we don't want to elevate to the user.
59     if (error.state() == GoogleServiceAuthError::NONE ||
60         error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
61       continue;
62     }
63 
64     std::string account_id = (*it)->GetAccountId();
65     std::string username = (*it)->GetUsername();
66 
67     // Prioritize this error if it matches the previous |auth_error_|.
68     if (error.state() == prev_state && account_id == prev_account_id) {
69       auth_error_ = error;
70       error_account_id_ = account_id;
71       error_username_ = username;
72       error_changed = true;
73       break;
74     }
75 
76     // Use this error if we haven't found one already, but keep looking for the
77     // previous |auth_error_| in case there's a match elsewhere in the set.
78     if (!error_changed) {
79       auth_error_ = error;
80       error_account_id_ = account_id;
81       error_username_ = username;
82       error_changed = true;
83     }
84   }
85 
86   if (!error_changed && prev_state != GoogleServiceAuthError::NONE) {
87     // No provider reported an error, so clear the error we have now.
88     auth_error_ = GoogleServiceAuthError::AuthErrorNone();
89     error_account_id_.clear();
90     error_username_.clear();
91     error_changed = true;
92   }
93 
94   if (error_changed) {
95     FOR_EACH_OBSERVER(Observer, observer_list_, OnErrorChanged());
96   }
97 }
98 
HasError() const99 bool SigninErrorController::HasError() const {
100   return auth_error_.state() != GoogleServiceAuthError::NONE &&
101       auth_error_.state() != GoogleServiceAuthError::CONNECTION_FAILED;
102 }
103 
AddObserver(Observer * observer)104 void SigninErrorController::AddObserver(Observer* observer) {
105   observer_list_.AddObserver(observer);
106 }
107 
RemoveObserver(Observer * observer)108 void SigninErrorController::RemoveObserver(Observer* observer) {
109   observer_list_.RemoveObserver(observer);
110 }
111