signin_error_controller.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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 7namespace { 8 9typedef std::set<const SigninErrorController::AuthStatusProvider*> 10 AuthStatusProviderSet; 11 12} // namespace 13 14SigninErrorController::AuthStatusProvider::AuthStatusProvider() { 15} 16 17SigninErrorController::AuthStatusProvider::~AuthStatusProvider() { 18} 19 20SigninErrorController::SigninErrorController() 21 : auth_error_(GoogleServiceAuthError::AuthErrorNone()) { 22} 23 24SigninErrorController::~SigninErrorController() { 25 DCHECK(provider_set_.empty()) 26 << "All AuthStatusProviders should be unregistered before" 27 << " SigninErrorController::Shutdown() is called"; 28} 29 30void 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 37void 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 45void 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 66 // Prioritize this error if it matches the previous |auth_error_|. 67 if (error.state() == prev_state && account_id == prev_account_id) { 68 auth_error_ = error; 69 error_account_id_ = account_id; 70 error_changed = true; 71 break; 72 } 73 74 // Use this error if we haven't found one already, but keep looking for the 75 // previous |auth_error_| in case there's a match elsewhere in the set. 76 if (!error_changed) { 77 auth_error_ = error; 78 error_account_id_ = account_id; 79 error_changed = true; 80 } 81 } 82 83 if (!error_changed && prev_state != GoogleServiceAuthError::NONE) { 84 // No provider reported an error, so clear the error we have now. 85 auth_error_ = GoogleServiceAuthError::AuthErrorNone(); 86 error_account_id_.clear(); 87 error_changed = true; 88 } 89 90 if (error_changed) { 91 FOR_EACH_OBSERVER(Observer, observer_list_, OnErrorChanged()); 92 } 93} 94 95bool SigninErrorController::HasError() const { 96 return auth_error_.state() != GoogleServiceAuthError::NONE && 97 auth_error_.state() != GoogleServiceAuthError::CONNECTION_FAILED; 98} 99 100void SigninErrorController::AddObserver(Observer* observer) { 101 observer_list_.AddObserver(observer); 102} 103 104void SigninErrorController::RemoveObserver(Observer* observer) { 105 observer_list_.RemoveObserver(observer); 106} 107