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