Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / components / signin / core / browser / signin_error_controller.cc
blob3d3060bc4c49425b9320b3f223abc20c56048252
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.
5 #include "components/signin/core/browser/signin_error_controller.h"
7 namespace {
9 typedef std::set<const SigninErrorController::AuthStatusProvider*>
10 AuthStatusProviderSet;
12 } // namespace
14 SigninErrorController::AuthStatusProvider::AuthStatusProvider() {
17 SigninErrorController::AuthStatusProvider::~AuthStatusProvider() {
20 SigninErrorController::SigninErrorController()
21 : auth_error_(GoogleServiceAuthError::AuthErrorNone()) {
24 SigninErrorController::~SigninErrorController() {
25 DCHECK(provider_set_.empty())
26 << "All AuthStatusProviders should be unregistered before"
27 << " SigninErrorController::Shutdown() is called";
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();
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();
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;
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();
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;
64 std::string account_id = (*it)->GetAccountId();
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;
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;
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;
90 if (error_changed) {
91 FOR_EACH_OBSERVER(Observer, observer_list_, OnErrorChanged());
95 bool SigninErrorController::HasError() const {
96 return auth_error_.state() != GoogleServiceAuthError::NONE &&
97 auth_error_.state() != GoogleServiceAuthError::CONNECTION_FAILED;
100 void SigninErrorController::AddObserver(Observer* observer) {
101 observer_list_.AddObserver(observer);
104 void SigninErrorController::RemoveObserver(Observer* observer) {
105 observer_list_.RemoveObserver(observer);