Port Android relocation packer to chromium build
[chromium-blink-merge.git] / components / signin / core / browser / signin_error_controller.cc
blob2d35e85209672d342f4ebf38da09d7f801588ffb
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 #include "components/signin/core/browser/signin_metrics.h"
9 namespace {
11 typedef std::set<const SigninErrorController::AuthStatusProvider*>
12 AuthStatusProviderSet;
14 } // namespace
16 SigninErrorController::AuthStatusProvider::AuthStatusProvider() {
19 SigninErrorController::AuthStatusProvider::~AuthStatusProvider() {
22 SigninErrorController::SigninErrorController()
23 : auth_error_(GoogleServiceAuthError::AuthErrorNone()) {
26 SigninErrorController::~SigninErrorController() {
27 DCHECK(provider_set_.empty())
28 << "All AuthStatusProviders should be unregistered before"
29 << " SigninErrorController::Shutdown() is called";
32 void SigninErrorController::AddProvider(const AuthStatusProvider* provider) {
33 DCHECK(provider_set_.find(provider) == provider_set_.end())
34 << "Adding same AuthStatusProvider multiple times";
35 provider_set_.insert(provider);
36 AuthStatusChanged();
39 void SigninErrorController::RemoveProvider(const AuthStatusProvider* provider) {
40 AuthStatusProviderSet::iterator iter = provider_set_.find(provider);
41 DCHECK(iter != provider_set_.end())
42 << "Removing provider that was never added";
43 provider_set_.erase(iter);
44 AuthStatusChanged();
47 void SigninErrorController::AuthStatusChanged() {
48 GoogleServiceAuthError::State prev_state = auth_error_.state();
49 std::string prev_account_id = error_account_id_;
50 bool error_changed = false;
52 // Find an error among the status providers. If |auth_error_| has an
53 // actionable error state and some provider exposes a similar error and
54 // account id, use that error. Otherwise, just take the first actionable
55 // error we find.
56 for (AuthStatusProviderSet::const_iterator it = provider_set_.begin();
57 it != provider_set_.end(); ++it) {
58 GoogleServiceAuthError error = (*it)->GetAuthStatus();
60 // Ignore the states we don't want to elevate to the user.
61 if (error.state() == GoogleServiceAuthError::NONE ||
62 error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
63 continue;
66 std::string account_id = (*it)->GetAccountId();
67 std::string username = (*it)->GetUsername();
69 // Prioritize this error if it matches the previous |auth_error_|.
70 if (error.state() == prev_state && account_id == prev_account_id) {
71 auth_error_ = error;
72 error_account_id_ = account_id;
73 error_username_ = username;
74 error_changed = true;
75 break;
78 // Use this error if we haven't found one already, but keep looking for the
79 // previous |auth_error_| in case there's a match elsewhere in the set.
80 if (!error_changed) {
81 auth_error_ = error;
82 error_account_id_ = account_id;
83 error_username_ = username;
84 error_changed = true;
88 if (!error_changed && prev_state != GoogleServiceAuthError::NONE) {
89 // No provider reported an error, so clear the error we have now.
90 auth_error_ = GoogleServiceAuthError::AuthErrorNone();
91 error_account_id_.clear();
92 error_username_.clear();
93 error_changed = true;
96 if (error_changed) {
97 signin_metrics::LogAuthError(auth_error_.state());
98 FOR_EACH_OBSERVER(Observer, observer_list_, OnErrorChanged());
102 bool SigninErrorController::HasError() const {
103 return auth_error_.state() != GoogleServiceAuthError::NONE &&
104 auth_error_.state() != GoogleServiceAuthError::CONNECTION_FAILED;
107 void SigninErrorController::AddObserver(Observer* observer) {
108 observer_list_.AddObserver(observer);
111 void SigninErrorController::RemoveObserver(Observer* observer) {
112 observer_list_.RemoveObserver(observer);