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