Home | History | Annotate | Download | only in signin
      1 // Copyright (c) 2012 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 "chrome/browser/signin/about_signin_internals.h"
      6 
      7 #include "base/debug/trace_event.h"
      8 #include "base/hash.h"
      9 #include "base/i18n/time_formatting.h"
     10 #include "base/logging.h"
     11 #include "base/prefs/pref_service.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/signin/signin_internals_util.h"
     15 #include "chrome/browser/signin/signin_manager.h"
     16 #include "chrome/browser/ui/webui/signin_internals_ui.h"
     17 #include "google_apis/gaia/gaia_constants.h"
     18 
     19 using base::Time;
     20 using namespace signin_internals_util;
     21 
     22 AboutSigninInternals::AboutSigninInternals() : profile_(NULL) {
     23 }
     24 
     25 AboutSigninInternals::~AboutSigninInternals() {
     26 }
     27 
     28 void AboutSigninInternals::AddSigninObserver(
     29     AboutSigninInternals::Observer* observer) {
     30   signin_observers_.AddObserver(observer);
     31 }
     32 
     33 void AboutSigninInternals::RemoveSigninObserver(
     34     AboutSigninInternals::Observer* observer) {
     35   signin_observers_.RemoveObserver(observer);
     36 }
     37 
     38 void AboutSigninInternals::NotifySigninValueChanged(
     39     const UntimedSigninStatusField& field,
     40     const std::string& value) {
     41   unsigned int field_index = field - UNTIMED_FIELDS_BEGIN;
     42   DCHECK(field_index >= 0 &&
     43          field_index < signin_status_.untimed_signin_fields.size());
     44 
     45   signin_status_.untimed_signin_fields[field_index] = value;
     46 
     47   // Also persist these values in the prefs.
     48   const std::string pref_path = SigninStatusFieldToString(field);
     49   profile_->GetPrefs()->SetString(pref_path.c_str(), value);
     50 
     51   NotifyObservers();
     52 }
     53 
     54 void AboutSigninInternals::NotifySigninValueChanged(
     55     const TimedSigninStatusField& field,
     56     const std::string& value) {
     57   unsigned int field_index = field - TIMED_FIELDS_BEGIN;
     58   DCHECK(field_index >= 0 &&
     59          field_index < signin_status_.timed_signin_fields.size());
     60 
     61   Time now = Time::NowFromSystemTime();
     62   std::string time_as_str = UTF16ToUTF8(base::TimeFormatFriendlyDate(now));
     63   TimedSigninStatusValue timed_value(value, time_as_str);
     64 
     65   signin_status_.timed_signin_fields[field_index] = timed_value;
     66 
     67   // Also persist these values in the prefs.
     68   const std::string value_pref = SigninStatusFieldToString(field) + ".value";
     69   const std::string time_pref = SigninStatusFieldToString(field) + ".time";
     70   profile_->GetPrefs()->SetString(value_pref.c_str(), value);
     71   profile_->GetPrefs()->SetString(time_pref.c_str(), time_as_str);
     72 
     73   NotifyObservers();
     74 }
     75 
     76 void AboutSigninInternals::RefreshSigninPrefs() {
     77   // Return if no profile exists. Can occur in unit tests.
     78   if (!profile_)
     79     return;
     80 
     81   PrefService* pref_service = profile_->GetPrefs();
     82   for (int i = UNTIMED_FIELDS_BEGIN; i < UNTIMED_FIELDS_END; ++i) {
     83     const std::string pref_path =
     84         SigninStatusFieldToString(static_cast<UntimedSigninStatusField>(i));
     85 
     86     // Erase SID and LSID, since those are written as service tokens below.
     87     if (i == signin_internals_util::SID || i == signin_internals_util::LSID)
     88       pref_service->SetString(pref_path.c_str(), std::string());
     89 
     90     signin_status_.untimed_signin_fields[i - UNTIMED_FIELDS_BEGIN] =
     91         pref_service->GetString(pref_path.c_str());
     92   }
     93   for (int i = TIMED_FIELDS_BEGIN ; i < TIMED_FIELDS_END; ++i) {
     94     const std::string value_pref = SigninStatusFieldToString(
     95         static_cast<TimedSigninStatusField>(i)) + ".value";
     96     const std::string time_pref = SigninStatusFieldToString(
     97         static_cast<TimedSigninStatusField>(i)) + ".time";
     98 
     99     TimedSigninStatusValue value(pref_service->GetString(value_pref.c_str()),
    100                                  pref_service->GetString(time_pref.c_str()));
    101     signin_status_.timed_signin_fields[i - TIMED_FIELDS_BEGIN] = value;
    102   }
    103 
    104   // TODO(rogerta): Get status and timestamps for oauth2 tokens.
    105 
    106   NotifyObservers();
    107 }
    108 
    109 void AboutSigninInternals::Initialize(Profile* profile) {
    110   DCHECK(!profile_);
    111   profile_ = profile;
    112 
    113   RefreshSigninPrefs();
    114 
    115   SigninManagerFactory::GetForProfile(profile)->
    116       AddSigninDiagnosticsObserver(this);
    117   // TODO(rogerta): observe OAuth2TokenService.
    118 }
    119 
    120 void AboutSigninInternals::Shutdown() {
    121   SigninManagerFactory::GetForProfile(profile_)->
    122       RemoveSigninDiagnosticsObserver(this);
    123 }
    124 
    125 void AboutSigninInternals::NotifyObservers() {
    126   FOR_EACH_OBSERVER(AboutSigninInternals::Observer,
    127                     signin_observers_,
    128                     OnSigninStateChanged(signin_status_.ToValue()));
    129 }
    130 
    131 scoped_ptr<DictionaryValue> AboutSigninInternals::GetSigninStatus() {
    132   return signin_status_.ToValue().Pass();
    133 }
    134 
    135 Time AboutSigninInternals::GetTokenTime(
    136     const std::string& token_name) const {
    137   TokenInfoMap::const_iterator iter =
    138       signin_status_.token_info_map.find(token_name);
    139   if (iter == signin_status_.token_info_map.end())
    140     return base::Time();
    141   return base::Time::FromInternalValue(iter->second.time_internal);
    142 }
    143