- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / gaia_info_update_service.cc
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/profiles/gaia_info_update_service.h"
6
7 #include "base/command_line.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/profiles/profile_info_cache.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/sync/profile_sync_service.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"
20
21 namespace {
22
23 // Update the user's GAIA info every 24 hours.
24 const int kUpdateIntervalHours = 24;
25
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;
29
30 } // namespace
31
32 GAIAInfoUpdateService::GAIAInfoUpdateService(Profile* profile)
33     : profile_(profile) {
34   PrefService* prefs = profile_->GetPrefs();
35   username_pref_.Init(prefs::kGoogleServicesUsername, prefs,
36                       base::Bind(&GAIAInfoUpdateService::OnUsernameChanged,
37                                  base::Unretained(this)));
38
39   last_updated_ = base::Time::FromInternalValue(
40       prefs->GetInt64(prefs::kProfileGAIAInfoUpdateTime));
41   ScheduleNextUpdate();
42 }
43
44 GAIAInfoUpdateService::~GAIAInfoUpdateService() {
45 }
46
47 void GAIAInfoUpdateService::Update() {
48   // The user must be logged in.
49   std::string username = profile_->GetPrefs()->GetString(
50       prefs::kGoogleServicesUsername);
51   if (username.empty())
52     return;
53
54   if (profile_image_downloader_)
55     return;
56   profile_image_downloader_.reset(new ProfileDownloader(this));
57   profile_image_downloader_->Start();
58 }
59
60 // static
61 bool GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(Profile* profile) {
62 #if defined(OS_CHROMEOS)
63   return false;
64 #endif
65
66   // Sync must be allowed.
67   if (!profile->GetOriginalProfile()->IsSyncAccessible())
68     return false;
69
70   // To enable this feature for testing pass "--google-profile-info".
71   if (CommandLine::ForCurrentProcess()->HasSwitch(
72       switches::kGoogleProfileInfo)) {
73     return true;
74   }
75
76   // This feature is disable by default.
77   return false;
78 }
79
80 bool GAIAInfoUpdateService::NeedsProfilePicture() const {
81   return true;
82 }
83
84 int GAIAInfoUpdateService::GetDesiredImageSideLength() const {
85   return 256;
86 }
87
88 Profile* GAIAInfoUpdateService::GetBrowserProfile() {
89   return profile_;
90 }
91
92 std::string GAIAInfoUpdateService::GetCachedPictureURL() const {
93   return profile_->GetPrefs()->GetString(prefs::kProfileGAIAInfoPictureURL);
94 }
95
96 void GAIAInfoUpdateService::OnProfileDownloadSuccess(
97     ProfileDownloader* downloader) {
98   // Make sure that |ProfileDownloader| gets deleted after return.
99   scoped_ptr<ProfileDownloader> profile_image_downloader(
100       profile_image_downloader_.release());
101
102   // Save the last updated time.
103   last_updated_ = base::Time::Now();
104   profile_->GetPrefs()->SetInt64(prefs::kProfileGAIAInfoUpdateTime,
105                                  last_updated_.ToInternalValue());
106   ScheduleNextUpdate();
107
108   string16 full_name = downloader->GetProfileFullName();
109   string16 given_name = downloader->GetProfileGivenName();
110   SkBitmap bitmap = downloader->GetProfilePicture();
111   ProfileDownloader::PictureStatus picture_status =
112       downloader->GetProfilePictureStatus();
113   std::string picture_url = downloader->GetProfilePictureURL();
114
115   ProfileInfoCache& cache =
116       g_browser_process->profile_manager()->GetProfileInfoCache();
117   size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
118   if (profile_index == std::string::npos)
119     return;
120
121   cache.SetGAIANameOfProfileAtIndex(profile_index, full_name);
122   cache.SetGAIAGivenNameOfProfileAtIndex(profile_index, given_name);
123
124   // The profile index may have changed.
125   profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
126   if (profile_index == std::string::npos)
127     return;
128   if (picture_status == ProfileDownloader::PICTURE_SUCCESS) {
129     profile_->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL,
130                                     picture_url);
131     gfx::Image gfx_image = gfx::Image::CreateFrom1xBitmap(bitmap);
132     cache.SetGAIAPictureOfProfileAtIndex(profile_index, &gfx_image);
133   } else if (picture_status == ProfileDownloader::PICTURE_DEFAULT) {
134     cache.SetGAIAPictureOfProfileAtIndex(profile_index, NULL);
135   }
136
137   // If this profile hasn't switched to using GAIA information for the profile
138   // name and picture then switch it now. Once the profile has switched this
139   // preference guards against clobbering the user's custom settings.
140   if (!cache.GetHasMigratedToGAIAInfoOfProfileAtIndex(profile_index)) {
141     cache.SetHasMigratedToGAIAInfoOfProfileAtIndex(profile_index, true);
142     // Order matters here for shortcut management, like in
143     // ProfileShortcutManagerWin::OnProfileAdded, as the picture update does not
144     // allow us to change the target, so we have to apply any renaming first. We
145     // also need to re-fetch the index, as SetIsUsingGAIANameOfProfileAtIndex
146     // may alter it.
147     cache.SetIsUsingGAIANameOfProfileAtIndex(profile_index, true);
148     profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
149     cache.SetIsUsingGAIAPictureOfProfileAtIndex(profile_index, true);
150   }
151 }
152
153 void GAIAInfoUpdateService::OnProfileDownloadFailure(
154     ProfileDownloader* downloader,
155     ProfileDownloaderDelegate::FailureReason reason) {
156   profile_image_downloader_.reset();
157
158   // Save the last updated time.
159   last_updated_ = base::Time::Now();
160   profile_->GetPrefs()->SetInt64(prefs::kProfileGAIAInfoUpdateTime,
161                                  last_updated_.ToInternalValue());
162   ScheduleNextUpdate();
163 }
164
165 void GAIAInfoUpdateService::OnUsernameChanged() {
166   ProfileInfoCache& cache =
167       g_browser_process->profile_manager()->GetProfileInfoCache();
168   size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
169   if (profile_index == std::string::npos)
170     return;
171
172   std::string username = profile_->GetPrefs()->GetString(
173       prefs::kGoogleServicesUsername);
174   if (username.empty()) {
175     // Unset the old user's GAIA info.
176     cache.SetGAIANameOfProfileAtIndex(profile_index, string16());
177     // The profile index may have changed.
178     profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
179     if (profile_index == std::string::npos)
180       return;
181     cache.SetGAIAPictureOfProfileAtIndex(profile_index, NULL);
182     // Unset the cached URL.
183     profile_->GetPrefs()->ClearPref(prefs::kProfileGAIAInfoPictureURL);
184   } else {
185     // Update the new user's GAIA info.
186     Update();
187   }
188 }
189
190 void GAIAInfoUpdateService::ScheduleNextUpdate() {
191   if (timer_.IsRunning())
192     return;
193
194   const base::TimeDelta desired_delta =
195       base::TimeDelta::FromHours(kUpdateIntervalHours);
196   const base::TimeDelta update_delta = base::Time::Now() - last_updated_;
197
198   base::TimeDelta delta;
199   if (update_delta < base::TimeDelta() || update_delta > desired_delta)
200     delta = base::TimeDelta::FromSeconds(kMinUpdateIntervalSeconds);
201   else
202     delta = desired_delta - update_delta;
203
204   timer_.Start(FROM_HERE, delta, this, &GAIAInfoUpdateService::Update);
205 }