• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AboutSigninInternals()22 AboutSigninInternals::AboutSigninInternals() : profile_(NULL) {
23 }
24 
~AboutSigninInternals()25 AboutSigninInternals::~AboutSigninInternals() {
26 }
27 
AddSigninObserver(AboutSigninInternals::Observer * observer)28 void AboutSigninInternals::AddSigninObserver(
29     AboutSigninInternals::Observer* observer) {
30   signin_observers_.AddObserver(observer);
31 }
32 
RemoveSigninObserver(AboutSigninInternals::Observer * observer)33 void AboutSigninInternals::RemoveSigninObserver(
34     AboutSigninInternals::Observer* observer) {
35   signin_observers_.RemoveObserver(observer);
36 }
37 
NotifySigninValueChanged(const UntimedSigninStatusField & field,const std::string & value)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 
NotifySigninValueChanged(const TimedSigninStatusField & field,const std::string & value)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 
RefreshSigninPrefs()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 
Initialize(Profile * profile)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 
Shutdown()120 void AboutSigninInternals::Shutdown() {
121   SigninManagerFactory::GetForProfile(profile_)->
122       RemoveSigninDiagnosticsObserver(this);
123 }
124 
NotifyObservers()125 void AboutSigninInternals::NotifyObservers() {
126   FOR_EACH_OBSERVER(AboutSigninInternals::Observer,
127                     signin_observers_,
128                     OnSigninStateChanged(signin_status_.ToValue()));
129 }
130 
GetSigninStatus()131 scoped_ptr<DictionaryValue> AboutSigninInternals::GetSigninStatus() {
132   return signin_status_.ToValue().Pass();
133 }
134 
GetTokenTime(const std::string & token_name) const135 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