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.
5 #include "chrome/browser/profiles/gaia_info_update_service.h"
7 #include "base/command_line.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/prefs/pref_service.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/profiles/profile_info_cache.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/sync/profile_sync_service.h"
14 #include "chrome/common/chrome_notification_types.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/public/browser/notification_details.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/gfx/image/image.h"
23 // Update the user's GAIA info every 24 hours.
24 const int kUpdateIntervalHours
= 24;
26 // If the users's GAIA info is very out of date then wait at least this long
27 // before starting an update. This avoids slowdown during startup.
28 const int kMinUpdateIntervalSeconds
= 5;
32 GAIAInfoUpdateService::GAIAInfoUpdateService(Profile
* profile
)
34 PrefService
* prefs
= profile_
->GetPrefs();
35 username_pref_
.Init(prefs::kGoogleServicesUsername
, prefs
, this);
37 last_updated_
= base::Time::FromInternalValue(
38 prefs
->GetInt64(prefs::kProfileGAIAInfoUpdateTime
));
42 GAIAInfoUpdateService::~GAIAInfoUpdateService() {
45 void GAIAInfoUpdateService::Update() {
46 // The user must be logged in.
47 std::string username
= profile_
->GetPrefs()->GetString(
48 prefs::kGoogleServicesUsername
);
52 if (profile_image_downloader_
.get())
54 profile_image_downloader_
.reset(new ProfileDownloader(this));
55 profile_image_downloader_
->Start();
59 bool GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(Profile
* profile
) {
60 #if defined(OS_CHROMEOS)
64 // Sync must be allowed.
65 if (!profile
->GetOriginalProfile()->IsSyncAccessible())
68 // To enable this feature for testing pass "--gaia-profile-info".
69 if (CommandLine::ForCurrentProcess()->HasSwitch(
70 switches::kGaiaProfileInfo
)) {
74 // This feature is disable by default.
79 void GAIAInfoUpdateService::RegisterUserPrefs(PrefServiceBase
* prefs
) {
80 prefs
->RegisterInt64Pref(
81 prefs::kProfileGAIAInfoUpdateTime
, 0, PrefServiceBase::UNSYNCABLE_PREF
);
82 prefs
->RegisterStringPref(
83 prefs::kProfileGAIAInfoPictureURL
, "", PrefServiceBase::UNSYNCABLE_PREF
);
86 bool GAIAInfoUpdateService::NeedsProfilePicture() const {
90 int GAIAInfoUpdateService::GetDesiredImageSideLength() const {
94 Profile
* GAIAInfoUpdateService::GetBrowserProfile() {
98 std::string
GAIAInfoUpdateService::GetCachedPictureURL() const {
99 return profile_
->GetPrefs()->GetString(prefs::kProfileGAIAInfoPictureURL
);
102 void GAIAInfoUpdateService::OnProfileDownloadSuccess(
103 ProfileDownloader
* downloader
) {
104 // Make sure that |ProfileDownloader| gets deleted after return.
105 scoped_ptr
<ProfileDownloader
> profile_image_downloader(
106 profile_image_downloader_
.release());
108 // Save the last updated time.
109 last_updated_
= base::Time::Now();
110 profile_
->GetPrefs()->SetInt64(prefs::kProfileGAIAInfoUpdateTime
,
111 last_updated_
.ToInternalValue());
112 ScheduleNextUpdate();
114 string16 full_name
= downloader
->GetProfileFullName();
115 SkBitmap bitmap
= downloader
->GetProfilePicture();
116 ProfileDownloader::PictureStatus picture_status
=
117 downloader
->GetProfilePictureStatus();
118 std::string picture_url
= downloader
->GetProfilePictureURL();
120 ProfileInfoCache
& cache
=
121 g_browser_process
->profile_manager()->GetProfileInfoCache();
122 size_t profile_index
= cache
.GetIndexOfProfileWithPath(profile_
->GetPath());
123 if (profile_index
== std::string::npos
)
126 cache
.SetGAIANameOfProfileAtIndex(profile_index
, full_name
);
127 // The profile index may have changed.
128 profile_index
= cache
.GetIndexOfProfileWithPath(profile_
->GetPath());
129 if (profile_index
== std::string::npos
)
131 if (picture_status
== ProfileDownloader::PICTURE_SUCCESS
) {
132 profile_
->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL
,
134 gfx::Image
gfx_image(bitmap
);
135 cache
.SetGAIAPictureOfProfileAtIndex(profile_index
, &gfx_image
);
136 } else if (picture_status
== ProfileDownloader::PICTURE_DEFAULT
) {
137 cache
.SetGAIAPictureOfProfileAtIndex(profile_index
, NULL
);
140 // If this profile hasn't switched to using GAIA information for the profile
141 // name and picture then switch it now. Once the profile has switched this
142 // preference guards against clobbering the user's custom settings.
143 if (!cache
.GetHasMigratedToGAIAInfoOfProfileAtIndex(profile_index
)) {
144 cache
.SetHasMigratedToGAIAInfoOfProfileAtIndex(profile_index
, true);
145 // Order matters here for shortcut management, like in
146 // ProfileShortcutManagerWin::OnProfileAdded, as the picture update does not
147 // allow us to change the target, so we have to apply any renaming first. We
148 // also need to re-fetch the index, as SetIsUsingGAIANameOfProfileAtIndex
150 cache
.SetIsUsingGAIANameOfProfileAtIndex(profile_index
, true);
151 profile_index
= cache
.GetIndexOfProfileWithPath(profile_
->GetPath());
152 cache
.SetIsUsingGAIAPictureOfProfileAtIndex(profile_index
, true);
156 void GAIAInfoUpdateService::OnProfileDownloadFailure(
157 ProfileDownloader
* downloader
) {
158 profile_image_downloader_
.reset();
160 // Save the last updated time.
161 last_updated_
= base::Time::Now();
162 profile_
->GetPrefs()->SetInt64(prefs::kProfileGAIAInfoUpdateTime
,
163 last_updated_
.ToInternalValue());
164 ScheduleNextUpdate();
167 void GAIAInfoUpdateService::OnPreferenceChanged(PrefServiceBase
* service
,
168 const std::string
& pref_name
) {
169 if (prefs::kGoogleServicesUsername
== pref_name
)
173 void GAIAInfoUpdateService::OnUsernameChanged() {
174 ProfileInfoCache
& cache
=
175 g_browser_process
->profile_manager()->GetProfileInfoCache();
176 size_t profile_index
= cache
.GetIndexOfProfileWithPath(profile_
->GetPath());
177 if (profile_index
== std::string::npos
)
180 std::string username
= profile_
->GetPrefs()->GetString(
181 prefs::kGoogleServicesUsername
);
182 if (username
.empty()) {
183 // Unset the old user's GAIA info.
184 cache
.SetGAIANameOfProfileAtIndex(profile_index
, string16());
185 // The profile index may have changed.
186 profile_index
= cache
.GetIndexOfProfileWithPath(profile_
->GetPath());
187 if (profile_index
== std::string::npos
)
189 cache
.SetGAIAPictureOfProfileAtIndex(profile_index
, NULL
);
190 // Unset the cached URL.
191 profile_
->GetPrefs()->ClearPref(prefs::kProfileGAIAInfoPictureURL
);
193 // Update the new user's GAIA info.
198 void GAIAInfoUpdateService::ScheduleNextUpdate() {
199 if (timer_
.IsRunning())
202 const base::TimeDelta desired_delta
=
203 base::TimeDelta::FromHours(kUpdateIntervalHours
);
204 const base::TimeDelta update_delta
= base::Time::Now() - last_updated_
;
206 base::TimeDelta delta
;
207 if (update_delta
< base::TimeDelta() || update_delta
> desired_delta
)
208 delta
= base::TimeDelta::FromSeconds(kMinUpdateIntervalSeconds
);
210 delta
= desired_delta
- update_delta
;
212 timer_
.Start(FROM_HERE
, delta
, this, &GAIAInfoUpdateService::Update
);