普通文本  |  143行  |  4.86 KB

// Copyright (c) 2012 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 "chrome/browser/signin/about_signin_internals.h"

#include "base/debug/trace_event.h"
#include "base/hash.h"
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/signin_internals_util.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/ui/webui/signin_internals_ui.h"
#include "google_apis/gaia/gaia_constants.h"

using base::Time;
using namespace signin_internals_util;

AboutSigninInternals::AboutSigninInternals() : profile_(NULL) {
}

AboutSigninInternals::~AboutSigninInternals() {
}

void AboutSigninInternals::AddSigninObserver(
    AboutSigninInternals::Observer* observer) {
  signin_observers_.AddObserver(observer);
}

void AboutSigninInternals::RemoveSigninObserver(
    AboutSigninInternals::Observer* observer) {
  signin_observers_.RemoveObserver(observer);
}

void AboutSigninInternals::NotifySigninValueChanged(
    const UntimedSigninStatusField& field,
    const std::string& value) {
  unsigned int field_index = field - UNTIMED_FIELDS_BEGIN;
  DCHECK(field_index >= 0 &&
         field_index < signin_status_.untimed_signin_fields.size());

  signin_status_.untimed_signin_fields[field_index] = value;

  // Also persist these values in the prefs.
  const std::string pref_path = SigninStatusFieldToString(field);
  profile_->GetPrefs()->SetString(pref_path.c_str(), value);

  NotifyObservers();
}

void AboutSigninInternals::NotifySigninValueChanged(
    const TimedSigninStatusField& field,
    const std::string& value) {
  unsigned int field_index = field - TIMED_FIELDS_BEGIN;
  DCHECK(field_index >= 0 &&
         field_index < signin_status_.timed_signin_fields.size());

  Time now = Time::NowFromSystemTime();
  std::string time_as_str = UTF16ToUTF8(base::TimeFormatFriendlyDate(now));
  TimedSigninStatusValue timed_value(value, time_as_str);

  signin_status_.timed_signin_fields[field_index] = timed_value;

  // Also persist these values in the prefs.
  const std::string value_pref = SigninStatusFieldToString(field) + ".value";
  const std::string time_pref = SigninStatusFieldToString(field) + ".time";
  profile_->GetPrefs()->SetString(value_pref.c_str(), value);
  profile_->GetPrefs()->SetString(time_pref.c_str(), time_as_str);

  NotifyObservers();
}

void AboutSigninInternals::RefreshSigninPrefs() {
  // Return if no profile exists. Can occur in unit tests.
  if (!profile_)
    return;

  PrefService* pref_service = profile_->GetPrefs();
  for (int i = UNTIMED_FIELDS_BEGIN; i < UNTIMED_FIELDS_END; ++i) {
    const std::string pref_path =
        SigninStatusFieldToString(static_cast<UntimedSigninStatusField>(i));

    // Erase SID and LSID, since those are written as service tokens below.
    if (i == signin_internals_util::SID || i == signin_internals_util::LSID)
      pref_service->SetString(pref_path.c_str(), std::string());

    signin_status_.untimed_signin_fields[i - UNTIMED_FIELDS_BEGIN] =
        pref_service->GetString(pref_path.c_str());
  }
  for (int i = TIMED_FIELDS_BEGIN ; i < TIMED_FIELDS_END; ++i) {
    const std::string value_pref = SigninStatusFieldToString(
        static_cast<TimedSigninStatusField>(i)) + ".value";
    const std::string time_pref = SigninStatusFieldToString(
        static_cast<TimedSigninStatusField>(i)) + ".time";

    TimedSigninStatusValue value(pref_service->GetString(value_pref.c_str()),
                                 pref_service->GetString(time_pref.c_str()));
    signin_status_.timed_signin_fields[i - TIMED_FIELDS_BEGIN] = value;
  }

  // TODO(rogerta): Get status and timestamps for oauth2 tokens.

  NotifyObservers();
}

void AboutSigninInternals::Initialize(Profile* profile) {
  DCHECK(!profile_);
  profile_ = profile;

  RefreshSigninPrefs();

  SigninManagerFactory::GetForProfile(profile)->
      AddSigninDiagnosticsObserver(this);
  // TODO(rogerta): observe OAuth2TokenService.
}

void AboutSigninInternals::Shutdown() {
  SigninManagerFactory::GetForProfile(profile_)->
      RemoveSigninDiagnosticsObserver(this);
}

void AboutSigninInternals::NotifyObservers() {
  FOR_EACH_OBSERVER(AboutSigninInternals::Observer,
                    signin_observers_,
                    OnSigninStateChanged(signin_status_.ToValue()));
}

scoped_ptr<DictionaryValue> AboutSigninInternals::GetSigninStatus() {
  return signin_status_.ToValue().Pass();
}

Time AboutSigninInternals::GetTokenTime(
    const std::string& token_name) const {
  TokenInfoMap::const_iterator iter =
      signin_status_.token_info_map.find(token_name);
  if (iter == signin_status_.token_info_map.end())
    return base::Time();
  return base::Time::FromInternalValue(iter->second.time_internal);
}