Update To 11.40.268.0
[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/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.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/profiles/profiles_state.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/browser/sync/profile_sync_service.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/signin/core/common/profile_management_switches.h"
19 #include "content/public/browser/notification_details.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "ui/gfx/image/image.h"
22
23 namespace {
24
25 // Update the user's GAIA info every 24 hours.
26 const int kUpdateIntervalHours = 24;
27
28 // If the users's GAIA info is very out of date then wait at least this long
29 // before starting an update. This avoids slowdown during startup.
30 const int kMinUpdateIntervalSeconds = 5;
31
32 }  // namespace
33
34 GAIAInfoUpdateService::GAIAInfoUpdateService(Profile* profile)
35     : profile_(profile) {
36   SigninManagerBase* signin_manager =
37       SigninManagerFactory::GetForProfile(profile_);
38   signin_manager->AddObserver(this);
39
40   PrefService* prefs = profile_->GetPrefs();
41   last_updated_ = base::Time::FromInternalValue(
42       prefs->GetInt64(prefs::kProfileGAIAInfoUpdateTime));
43   ScheduleNextUpdate();
44 }
45
46 GAIAInfoUpdateService::~GAIAInfoUpdateService() {
47   DCHECK(!profile_) << "Shutdown not called before dtor";
48 }
49
50 void GAIAInfoUpdateService::Update() {
51   // The user must be logged in.
52   SigninManagerBase* signin_manager =
53       SigninManagerFactory::GetForProfile(profile_);
54   if (!signin_manager->IsAuthenticated())
55     return;
56
57   if (profile_image_downloader_)
58     return;
59   profile_image_downloader_.reset(new ProfileDownloader(this));
60   profile_image_downloader_->Start();
61 }
62
63 // static
64 bool GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(Profile* profile) {
65 #if defined(OS_CHROMEOS)
66   return false;
67 #endif
68
69   // Sync must be allowed.
70   if (!profile->GetOriginalProfile()->IsSyncAccessible())
71     return false;
72
73   // To enable this feature for testing pass "--google-profile-info".
74   if (switches::IsGoogleProfileInfo())
75     return true;
76
77   // This feature is disable by default.
78   return false;
79 }
80
81 bool GAIAInfoUpdateService::NeedsProfilePicture() const {
82   return true;
83 }
84
85 int GAIAInfoUpdateService::GetDesiredImageSideLength() const {
86   return 256;
87 }
88
89 Profile* GAIAInfoUpdateService::GetBrowserProfile() {
90   return profile_;
91 }
92
93 std::string GAIAInfoUpdateService::GetCachedPictureURL() const {
94   return profile_->GetPrefs()->GetString(prefs::kProfileGAIAInfoPictureURL);
95 }
96
97 void GAIAInfoUpdateService::OnProfileDownloadSuccess(
98     ProfileDownloader* downloader) {
99   // Make sure that |ProfileDownloader| gets deleted after return.
100   scoped_ptr<ProfileDownloader> profile_image_downloader(
101       profile_image_downloader_.release());
102
103   // Save the last updated time.
104   last_updated_ = base::Time::Now();
105   profile_->GetPrefs()->SetInt64(prefs::kProfileGAIAInfoUpdateTime,
106                                  last_updated_.ToInternalValue());
107   ScheduleNextUpdate();
108
109   base::string16 full_name = downloader->GetProfileFullName();
110   base::string16 given_name = downloader->GetProfileGivenName();
111   SkBitmap bitmap = downloader->GetProfilePicture();
112   ProfileDownloader::PictureStatus picture_status =
113       downloader->GetProfilePictureStatus();
114   std::string picture_url = downloader->GetProfilePictureURL();
115
116   ProfileInfoCache& cache =
117       g_browser_process->profile_manager()->GetProfileInfoCache();
118   size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
119   if (profile_index == std::string::npos)
120     return;
121
122   cache.SetGAIANameOfProfileAtIndex(profile_index, full_name);
123   // The profile index may have changed.
124   profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
125   DCHECK_NE(profile_index, std::string::npos);
126
127   cache.SetGAIAGivenNameOfProfileAtIndex(profile_index, given_name);
128   // The profile index may have changed.
129   profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
130   DCHECK_NE(profile_index, std::string::npos);
131
132   if (picture_status == ProfileDownloader::PICTURE_SUCCESS) {
133     profile_->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL,
134                                     picture_url);
135     gfx::Image gfx_image = gfx::Image::CreateFrom1xBitmap(bitmap);
136     cache.SetGAIAPictureOfProfileAtIndex(profile_index, &gfx_image);
137   } else if (picture_status == ProfileDownloader::PICTURE_DEFAULT) {
138     cache.SetGAIAPictureOfProfileAtIndex(profile_index, NULL);
139   }
140
141   const base::string16 hosted_domain = downloader->GetProfileHostedDomain();
142   profile_->GetPrefs()->SetString(prefs::kGoogleServicesHostedDomain,
143       (hosted_domain.empty() ? Profile::kNoHostedDomainFound :
144                                base::UTF16ToUTF8(hosted_domain)));
145 }
146
147 void GAIAInfoUpdateService::OnProfileDownloadFailure(
148     ProfileDownloader* downloader,
149     ProfileDownloaderDelegate::FailureReason reason) {
150   profile_image_downloader_.reset();
151
152   // Save the last updated time.
153   last_updated_ = base::Time::Now();
154   profile_->GetPrefs()->SetInt64(prefs::kProfileGAIAInfoUpdateTime,
155                                  last_updated_.ToInternalValue());
156   ScheduleNextUpdate();
157 }
158
159 void GAIAInfoUpdateService::OnUsernameChanged(const std::string& username) {
160   ProfileInfoCache& cache =
161       g_browser_process->profile_manager()->GetProfileInfoCache();
162   size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
163   if (profile_index == std::string::npos)
164     return;
165
166   if (username.empty()) {
167     // Unset the old user's GAIA info.
168     cache.SetGAIANameOfProfileAtIndex(profile_index, base::string16());
169     cache.SetGAIAGivenNameOfProfileAtIndex(profile_index, base::string16());
170     // The profile index may have changed.
171     profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
172     if (profile_index == std::string::npos)
173       return;
174     cache.SetGAIAPictureOfProfileAtIndex(profile_index, NULL);
175     // Unset the cached URL.
176     profile_->GetPrefs()->ClearPref(prefs::kProfileGAIAInfoPictureURL);
177   } else {
178     // Update the new user's GAIA info.
179     Update();
180   }
181 }
182
183 void GAIAInfoUpdateService::Shutdown() {
184   timer_.Stop();
185   profile_image_downloader_.reset();
186   SigninManagerBase* signin_manager =
187       SigninManagerFactory::GetForProfile(profile_);
188   signin_manager->RemoveObserver(this);
189
190   // OK to reset |profile_| pointer here because GAIAInfoUpdateService will not
191   // access it again.  This pointer is also used to implement the delegate for
192   // |profile_image_downloader_|.  However that object was destroyed above.
193   profile_ = NULL;
194 }
195
196 void GAIAInfoUpdateService::ScheduleNextUpdate() {
197   if (timer_.IsRunning())
198     return;
199
200   const base::TimeDelta desired_delta =
201       base::TimeDelta::FromHours(kUpdateIntervalHours);
202   const base::TimeDelta update_delta = base::Time::Now() - last_updated_;
203
204   base::TimeDelta delta;
205   if (update_delta < base::TimeDelta() || update_delta > desired_delta)
206     delta = base::TimeDelta::FromSeconds(kMinUpdateIntervalSeconds);
207   else
208     delta = desired_delta - update_delta;
209
210   timer_.Start(FROM_HERE, delta, this, &GAIAInfoUpdateService::Update);
211 }
212
213 void GAIAInfoUpdateService::GoogleSigninSucceeded(
214     const std::string& account_id,
215     const std::string& username,
216     const std::string& password) {
217   OnUsernameChanged(username);
218 }
219
220 void GAIAInfoUpdateService::GoogleSignedOut(const std::string& account_id,
221                                             const std::string& username) {
222   OnUsernameChanged(std::string());
223 }