| // 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); |
| } |