root/components/signin/core/browser/signin_error_controller.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. AddProvider
  2. RemoveProvider
  3. AuthStatusChanged
  4. HasError
  5. AddObserver
  6. RemoveObserver

// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/signin/core/browser/signin_error_controller.h"

namespace {

typedef std::set<const SigninErrorController::AuthStatusProvider*>
    AuthStatusProviderSet;

}  // namespace

SigninErrorController::AuthStatusProvider::AuthStatusProvider() {
}

SigninErrorController::AuthStatusProvider::~AuthStatusProvider() {
}

SigninErrorController::SigninErrorController()
    : auth_error_(GoogleServiceAuthError::AuthErrorNone()) {
}

SigninErrorController::~SigninErrorController() {
  DCHECK(provider_set_.empty())
      << "All AuthStatusProviders should be unregistered before"
      << " SigninErrorController::Shutdown() is called";
}

void SigninErrorController::AddProvider(const AuthStatusProvider* provider) {
  DCHECK(provider_set_.find(provider) == provider_set_.end())
      << "Adding same AuthStatusProvider multiple times";
  provider_set_.insert(provider);
  AuthStatusChanged();
}

void SigninErrorController::RemoveProvider(const AuthStatusProvider* provider) {
  AuthStatusProviderSet::iterator iter = provider_set_.find(provider);
  DCHECK(iter != provider_set_.end())
      << "Removing provider that was never added";
  provider_set_.erase(iter);
  AuthStatusChanged();
}

void SigninErrorController::AuthStatusChanged() {
  GoogleServiceAuthError::State prev_state = auth_error_.state();
  std::string prev_account_id = error_account_id_;
  bool error_changed = false;

  // Find an error among the status providers. If |auth_error_| has an
  // actionable error state and some provider exposes a similar error and
  // account id, use that error. Otherwise, just take the first actionable
  // error we find.
  for (AuthStatusProviderSet::const_iterator it = provider_set_.begin();
       it != provider_set_.end(); ++it) {
    GoogleServiceAuthError error = (*it)->GetAuthStatus();

    // Ignore the states we don't want to elevate to the user.
    if (error.state() == GoogleServiceAuthError::NONE ||
        error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
      continue;
    }

    std::string account_id = (*it)->GetAccountId();

    // Prioritize this error if it matches the previous |auth_error_|.
    if (error.state() == prev_state && account_id == prev_account_id) {
      auth_error_ = error;
      error_account_id_ = account_id;
      error_changed = true;
      break;
    }

    // Use this error if we haven't found one already, but keep looking for the
    // previous |auth_error_| in case there's a match elsewhere in the set.
    if (!error_changed) {
      auth_error_ = error;
      error_account_id_ = account_id;
      error_changed = true;
    }
  }

  if (!error_changed && prev_state != GoogleServiceAuthError::NONE) {
    // No provider reported an error, so clear the error we have now.
    auth_error_ = GoogleServiceAuthError::AuthErrorNone();
    error_account_id_.clear();
    error_changed = true;
  }

  if (error_changed) {
    FOR_EACH_OBSERVER(Observer, observer_list_, OnErrorChanged());
  }
}

bool SigninErrorController::HasError() const {
  return auth_error_.state() != GoogleServiceAuthError::NONE &&
      auth_error_.state() != GoogleServiceAuthError::CONNECTION_FAILED;
}

void SigninErrorController::AddObserver(Observer* observer) {
  observer_list_.AddObserver(observer);
}

void SigninErrorController::RemoveObserver(Observer* observer) {
  observer_list_.RemoveObserver(observer);
}

/* [<][>][^][v][top][bottom][index][help] */