| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h" | 5 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop_proxy.h" | 12 #include "base/message_loop/message_loop_proxy.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/prefs/pref_registry_simple.h" | 15 #include "base/prefs/pref_registry_simple.h" |
| 16 #include "base/prefs/pref_service.h" | 16 #include "base/prefs/pref_service.h" |
| 17 #include "base/prefs/scoped_user_pref_update.h" | 17 #include "base/prefs/scoped_user_pref_update.h" |
| 18 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| 19 #include "base/sequenced_task_runner.h" | 19 #include "base/sequenced_task_runner.h" |
| 20 #include "base/task_runner_util.h" | 20 #include "base/task_runner_util.h" |
| 21 #include "base/threading/sequenced_worker_pool.h" | 21 #include "base/threading/sequenced_worker_pool.h" |
| 22 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 23 #include "base/values.h" | 23 #include "base/values.h" |
| 24 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
| 25 #include "chrome/browser/chrome_notification_types.h" | 25 #include "chrome/browser/chrome_notification_types.h" |
| 26 #include "chrome/browser/chromeos/login/helper.h" | 26 #include "chrome/browser/chromeos/login/helper.h" |
| 27 #include "chrome/browser/chromeos/login/users/avatar/default_user_images.h" | 27 #include "chrome/browser/chromeos/login/users/avatar/default_user_images.h" |
| 28 #include "chrome/browser/chromeos/login/users/avatar/user_image.h" | |
| 29 #include "chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.h" | 28 #include "chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.h" |
| 30 #include "chrome/browser/chromeos/login/users/user_manager.h" | 29 #include "chrome/browser/chromeos/login/users/user_manager.h" |
| 31 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 30 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 32 #include "chrome/browser/profiles/profile_downloader.h" | 31 #include "chrome/browser/profiles/profile_downloader.h" |
| 33 #include "chrome/browser/profiles/profile_manager.h" | 32 #include "chrome/browser/profiles/profile_manager.h" |
| 34 #include "chrome/common/chrome_paths.h" | 33 #include "chrome/common/chrome_paths.h" |
| 34 #include "components/user_manager/avatar/user_image.h" |
| 35 #include "components/user_manager/user_type.h" | 35 #include "components/user_manager/user_type.h" |
| 36 #include "content/public/browser/browser_thread.h" | 36 #include "content/public/browser/browser_thread.h" |
| 37 #include "content/public/browser/notification_service.h" | 37 #include "content/public/browser/notification_service.h" |
| 38 #include "policy/policy_constants.h" | 38 #include "policy/policy_constants.h" |
| 39 #include "ui/gfx/image/image_skia.h" | 39 #include "ui/gfx/image/image_skia.h" |
| 40 | 40 |
| 41 namespace chromeos { | 41 namespace chromeos { |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 case User::kExternalImageIndex: | 148 case User::kExternalImageIndex: |
| 149 // TODO(ivankr): Distinguish this from selected from file. | 149 // TODO(ivankr): Distinguish this from selected from file. |
| 150 return kHistogramImageFromCamera; | 150 return kHistogramImageFromCamera; |
| 151 case User::kProfileImageIndex: | 151 case User::kProfileImageIndex: |
| 152 return kHistogramImageFromProfile; | 152 return kHistogramImageFromProfile; |
| 153 default: | 153 default: |
| 154 return image_index; | 154 return image_index; |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 | 157 |
| 158 bool SaveImage(const UserImage& user_image, const base::FilePath& image_path) { | 158 bool SaveImage(const user_manager::UserImage& user_image, |
| 159 UserImage safe_image; | 159 const base::FilePath& image_path) { |
| 160 const UserImage::RawImage* encoded_image = NULL; | 160 user_manager::UserImage safe_image; |
| 161 const user_manager::UserImage::RawImage* encoded_image = NULL; |
| 161 if (!user_image.is_safe_format()) { | 162 if (!user_image.is_safe_format()) { |
| 162 safe_image = UserImage::CreateAndEncode(user_image.image()); | 163 safe_image = user_manager::UserImage::CreateAndEncode(user_image.image()); |
| 163 encoded_image = &safe_image.raw_image(); | 164 encoded_image = &safe_image.raw_image(); |
| 164 UMA_HISTOGRAM_MEMORY_KB("UserImage.RecodedJpegSize", encoded_image->size()); | 165 UMA_HISTOGRAM_MEMORY_KB("UserImage.RecodedJpegSize", encoded_image->size()); |
| 165 } else if (user_image.has_raw_image()) { | 166 } else if (user_image.has_raw_image()) { |
| 166 encoded_image = &user_image.raw_image(); | 167 encoded_image = &user_image.raw_image(); |
| 167 } else { | 168 } else { |
| 168 NOTREACHED() << "Raw image missing."; | 169 NOTREACHED() << "Raw image missing."; |
| 169 return false; | 170 return false; |
| 170 } | 171 } |
| 171 | 172 |
| 172 if (!encoded_image->size() || | 173 if (!encoded_image->size() || |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 const int image_index, | 210 const int image_index, |
| 210 const GURL& image_url); | 211 const GURL& image_url); |
| 211 | 212 |
| 212 // Sets the user image in local state to the default image indicated | 213 // Sets the user image in local state to the default image indicated |
| 213 // by |default_image_index|. Also updates the user object with the | 214 // by |default_image_index|. Also updates the user object with the |
| 214 // new image. | 215 // new image. |
| 215 void SetToDefaultImage(int default_image_index); | 216 void SetToDefaultImage(int default_image_index); |
| 216 | 217 |
| 217 // Saves the |user_image| to disk and sets the user image in local | 218 // Saves the |user_image| to disk and sets the user image in local |
| 218 // state to that image. Also updates the user with the new image. | 219 // state to that image. Also updates the user with the new image. |
| 219 void SetToImage(int image_index, const UserImage& user_image); | 220 void SetToImage(int image_index, const user_manager::UserImage& user_image); |
| 220 | 221 |
| 221 // Decodes the JPEG image |data|, crops and resizes the image, saves | 222 // Decodes the JPEG image |data|, crops and resizes the image, saves |
| 222 // it to disk and sets the user image in local state to that image. | 223 // it to disk and sets the user image in local state to that image. |
| 223 // Also updates the user object with the new image. | 224 // Also updates the user object with the new image. |
| 224 void SetToImageData(scoped_ptr<std::string> data); | 225 void SetToImageData(scoped_ptr<std::string> data); |
| 225 | 226 |
| 226 // Loads the image at |path|, transcodes it to JPEG format, saves | 227 // Loads the image at |path|, transcodes it to JPEG format, saves |
| 227 // the image to disk and sets the user image in local state to that | 228 // the image to disk and sets the user image in local state to that |
| 228 // image. If |resize| is true, the image is cropped and resized | 229 // image. If |resize| is true, the image is cropped and resized |
| 229 // before transcoding. Also updates the user object with the new | 230 // before transcoding. Also updates the user object with the new |
| 230 // image. | 231 // image. |
| 231 void SetToPath(const base::FilePath& path, | 232 void SetToPath(const base::FilePath& path, |
| 232 int image_index, | 233 int image_index, |
| 233 const GURL& image_url, | 234 const GURL& image_url, |
| 234 bool resize); | 235 bool resize); |
| 235 | 236 |
| 236 private: | 237 private: |
| 237 // Called back after an image has been loaded from disk. | 238 // Called back after an image has been loaded from disk. |
| 238 void OnLoadImageDone(bool save, const UserImage& user_image); | 239 void OnLoadImageDone(bool save, const user_manager::UserImage& user_image); |
| 239 | 240 |
| 240 // Updates the user object with |user_image_|. | 241 // Updates the user object with |user_image_|. |
| 241 void UpdateUser(); | 242 void UpdateUser(); |
| 242 | 243 |
| 243 // Saves |user_image_| to disk in JPEG format. Local state will be updated | 244 // Saves |user_image_| to disk in JPEG format. Local state will be updated |
| 244 // when a callback indicates that the image has been saved. | 245 // when a callback indicates that the image has been saved. |
| 245 void SaveImageAndUpdateLocalState(); | 246 void SaveImageAndUpdateLocalState(); |
| 246 | 247 |
| 247 // Called back after the |user_image_| has been saved to | 248 // Called back after the |user_image_| has been saved to |
| 248 // disk. Updates the user image information in local state. The | 249 // disk. Updates the user image information in local state. The |
| (...skipping 16 matching lines...) Expand all Loading... |
| 265 | 266 |
| 266 UserImageManagerImpl* parent_; | 267 UserImageManagerImpl* parent_; |
| 267 | 268 |
| 268 // Whether one of the Load*() or Set*() methods has been run already. | 269 // Whether one of the Load*() or Set*() methods has been run already. |
| 269 bool run_; | 270 bool run_; |
| 270 | 271 |
| 271 int image_index_; | 272 int image_index_; |
| 272 GURL image_url_; | 273 GURL image_url_; |
| 273 base::FilePath image_path_; | 274 base::FilePath image_path_; |
| 274 | 275 |
| 275 UserImage user_image_; | 276 user_manager::UserImage user_image_; |
| 276 | 277 |
| 277 base::WeakPtrFactory<Job> weak_factory_; | 278 base::WeakPtrFactory<Job> weak_factory_; |
| 278 | 279 |
| 279 DISALLOW_COPY_AND_ASSIGN(Job); | 280 DISALLOW_COPY_AND_ASSIGN(Job); |
| 280 }; | 281 }; |
| 281 | 282 |
| 282 UserImageManagerImpl::Job::Job(UserImageManagerImpl* parent) | 283 UserImageManagerImpl::Job::Job(UserImageManagerImpl* parent) |
| 283 : parent_(parent), | 284 : parent_(parent), |
| 284 run_(false), | 285 run_(false), |
| 285 weak_factory_(this) { | 286 weak_factory_(this) { |
| 286 } | 287 } |
| 287 | 288 |
| 288 UserImageManagerImpl::Job::~Job() { | 289 UserImageManagerImpl::Job::~Job() { |
| 289 } | 290 } |
| 290 | 291 |
| 291 void UserImageManagerImpl::Job::LoadImage(base::FilePath image_path, | 292 void UserImageManagerImpl::Job::LoadImage(base::FilePath image_path, |
| 292 const int image_index, | 293 const int image_index, |
| 293 const GURL& image_url) { | 294 const GURL& image_url) { |
| 294 DCHECK(!run_); | 295 DCHECK(!run_); |
| 295 run_ = true; | 296 run_ = true; |
| 296 | 297 |
| 297 image_index_ = image_index; | 298 image_index_ = image_index; |
| 298 image_url_ = image_url; | 299 image_url_ = image_url; |
| 299 image_path_ = image_path; | 300 image_path_ = image_path; |
| 300 | 301 |
| 301 if (image_index_ >= 0 && image_index_ < kDefaultImagesCount) { | 302 if (image_index_ >= 0 && image_index_ < kDefaultImagesCount) { |
| 302 // Load one of the default images. This happens synchronously. | 303 // Load one of the default images. This happens synchronously. |
| 303 user_image_ = UserImage(GetDefaultImage(image_index_)); | 304 user_image_ = user_manager::UserImage(GetDefaultImage(image_index_)); |
| 304 UpdateUser(); | 305 UpdateUser(); |
| 305 NotifyJobDone(); | 306 NotifyJobDone(); |
| 306 } else if (image_index_ == User::kExternalImageIndex || | 307 } else if (image_index_ == User::kExternalImageIndex || |
| 307 image_index_ == User::kProfileImageIndex) { | 308 image_index_ == User::kProfileImageIndex) { |
| 308 // Load the user image from a file referenced by |image_path|. This happens | 309 // Load the user image from a file referenced by |image_path|. This happens |
| 309 // asynchronously. The JPEG image loader can be used here because | 310 // asynchronously. The JPEG image loader can be used here because |
| 310 // LoadImage() is called only for users whose user image has previously | 311 // LoadImage() is called only for users whose user image has previously |
| 311 // been set by one of the Set*() methods, which transcode to JPEG format. | 312 // been set by one of the Set*() methods, which transcode to JPEG format. |
| 312 DCHECK(!image_path_.empty()); | 313 DCHECK(!image_path_.empty()); |
| 313 parent_->image_loader_->Start(image_path_.value(), | 314 parent_->image_loader_->Start(image_path_.value(), |
| 314 0, | 315 0, |
| 315 base::Bind(&Job::OnLoadImageDone, | 316 base::Bind(&Job::OnLoadImageDone, |
| 316 weak_factory_.GetWeakPtr(), | 317 weak_factory_.GetWeakPtr(), |
| 317 false)); | 318 false)); |
| 318 } else { | 319 } else { |
| 319 NOTREACHED(); | 320 NOTREACHED(); |
| 320 NotifyJobDone(); | 321 NotifyJobDone(); |
| 321 } | 322 } |
| 322 } | 323 } |
| 323 | 324 |
| 324 void UserImageManagerImpl::Job::SetToDefaultImage(int default_image_index) { | 325 void UserImageManagerImpl::Job::SetToDefaultImage(int default_image_index) { |
| 325 DCHECK(!run_); | 326 DCHECK(!run_); |
| 326 run_ = true; | 327 run_ = true; |
| 327 | 328 |
| 328 DCHECK_LE(0, default_image_index); | 329 DCHECK_LE(0, default_image_index); |
| 329 DCHECK_GT(kDefaultImagesCount, default_image_index); | 330 DCHECK_GT(kDefaultImagesCount, default_image_index); |
| 330 | 331 |
| 331 image_index_ = default_image_index; | 332 image_index_ = default_image_index; |
| 332 user_image_ = UserImage(GetDefaultImage(image_index_)); | 333 user_image_ = user_manager::UserImage(GetDefaultImage(image_index_)); |
| 333 | 334 |
| 334 UpdateUser(); | 335 UpdateUser(); |
| 335 UpdateLocalState(); | 336 UpdateLocalState(); |
| 336 NotifyJobDone(); | 337 NotifyJobDone(); |
| 337 } | 338 } |
| 338 | 339 |
| 339 void UserImageManagerImpl::Job::SetToImage(int image_index, | 340 void UserImageManagerImpl::Job::SetToImage( |
| 340 const UserImage& user_image) { | 341 int image_index, |
| 342 const user_manager::UserImage& user_image) { |
| 341 DCHECK(!run_); | 343 DCHECK(!run_); |
| 342 run_ = true; | 344 run_ = true; |
| 343 | 345 |
| 344 DCHECK(image_index == User::kExternalImageIndex || | 346 DCHECK(image_index == User::kExternalImageIndex || |
| 345 image_index == User::kProfileImageIndex); | 347 image_index == User::kProfileImageIndex); |
| 346 | 348 |
| 347 image_index_ = image_index; | 349 image_index_ = image_index; |
| 348 user_image_ = user_image; | 350 user_image_ = user_image; |
| 349 | 351 |
| 350 UpdateUser(); | 352 UpdateUser(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 image_url_ = image_url; | 387 image_url_ = image_url; |
| 386 | 388 |
| 387 DCHECK(!path.empty()); | 389 DCHECK(!path.empty()); |
| 388 parent_->unsafe_image_loader_->Start(path.value(), | 390 parent_->unsafe_image_loader_->Start(path.value(), |
| 389 resize ? login::kMaxUserImageSize : 0, | 391 resize ? login::kMaxUserImageSize : 0, |
| 390 base::Bind(&Job::OnLoadImageDone, | 392 base::Bind(&Job::OnLoadImageDone, |
| 391 weak_factory_.GetWeakPtr(), | 393 weak_factory_.GetWeakPtr(), |
| 392 true)); | 394 true)); |
| 393 } | 395 } |
| 394 | 396 |
| 395 void UserImageManagerImpl::Job::OnLoadImageDone(bool save, | 397 void UserImageManagerImpl::Job::OnLoadImageDone( |
| 396 const UserImage& user_image) { | 398 bool save, |
| 399 const user_manager::UserImage& user_image) { |
| 397 user_image_ = user_image; | 400 user_image_ = user_image; |
| 398 UpdateUser(); | 401 UpdateUser(); |
| 399 if (save) | 402 if (save) |
| 400 SaveImageAndUpdateLocalState(); | 403 SaveImageAndUpdateLocalState(); |
| 401 else | 404 else |
| 402 NotifyJobDone(); | 405 NotifyJobDone(); |
| 403 } | 406 } |
| 404 | 407 |
| 405 void UserImageManagerImpl::Job::UpdateUser() { | 408 void UserImageManagerImpl::Job::UpdateUser() { |
| 406 User* user = parent_->user_manager_->FindUserAndModify(user_id()); | 409 User* user = parent_->user_manager_->FindUserAndModify(user_id()); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 return; | 515 return; |
| 513 | 516 |
| 514 if (!image_properties) { | 517 if (!image_properties) { |
| 515 SetInitialUserImage(); | 518 SetInitialUserImage(); |
| 516 return; | 519 return; |
| 517 } | 520 } |
| 518 | 521 |
| 519 int image_index = User::kInvalidImageIndex; | 522 int image_index = User::kInvalidImageIndex; |
| 520 image_properties->GetInteger(kImageIndexNodeName, &image_index); | 523 image_properties->GetInteger(kImageIndexNodeName, &image_index); |
| 521 if (image_index >= 0 && image_index < kDefaultImagesCount) { | 524 if (image_index >= 0 && image_index < kDefaultImagesCount) { |
| 522 user->SetImage(UserImage(GetDefaultImage(image_index)), | 525 user->SetImage(user_manager::UserImage(GetDefaultImage(image_index)), |
| 523 image_index); | 526 image_index); |
| 524 return; | 527 return; |
| 525 } | 528 } |
| 526 | 529 |
| 527 if (image_index != User::kExternalImageIndex && | 530 if (image_index != User::kExternalImageIndex && |
| 528 image_index != User::kProfileImageIndex) { | 531 image_index != User::kProfileImageIndex) { |
| 529 NOTREACHED(); | 532 NOTREACHED(); |
| 530 return; | 533 return; |
| 531 } | 534 } |
| 532 | 535 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 TryToCreateImageSyncObserver(); | 621 TryToCreateImageSyncObserver(); |
| 619 } | 622 } |
| 620 | 623 |
| 621 void UserImageManagerImpl::SaveUserDefaultImageIndex(int default_image_index) { | 624 void UserImageManagerImpl::SaveUserDefaultImageIndex(int default_image_index) { |
| 622 if (IsUserImageManaged()) | 625 if (IsUserImageManaged()) |
| 623 return; | 626 return; |
| 624 job_.reset(new Job(this)); | 627 job_.reset(new Job(this)); |
| 625 job_->SetToDefaultImage(default_image_index); | 628 job_->SetToDefaultImage(default_image_index); |
| 626 } | 629 } |
| 627 | 630 |
| 628 void UserImageManagerImpl::SaveUserImage(const UserImage& user_image) { | 631 void UserImageManagerImpl::SaveUserImage( |
| 632 const user_manager::UserImage& user_image) { |
| 629 if (IsUserImageManaged()) | 633 if (IsUserImageManaged()) |
| 630 return; | 634 return; |
| 631 job_.reset(new Job(this)); | 635 job_.reset(new Job(this)); |
| 632 job_->SetToImage(User::kExternalImageIndex, user_image); | 636 job_->SetToImage(User::kExternalImageIndex, user_image); |
| 633 } | 637 } |
| 634 | 638 |
| 635 void UserImageManagerImpl::SaveUserImageFromFile(const base::FilePath& path) { | 639 void UserImageManagerImpl::SaveUserImageFromFile(const base::FilePath& path) { |
| 636 if (IsUserImageManaged()) | 640 if (IsUserImageManaged()) |
| 637 return; | 641 return; |
| 638 job_.reset(new Job(this)); | 642 job_.reset(new Job(this)); |
| 639 job_->SetToPath(path, User::kExternalImageIndex, GURL(), true); | 643 job_->SetToPath(path, User::kExternalImageIndex, GURL(), true); |
| 640 } | 644 } |
| 641 | 645 |
| 642 void UserImageManagerImpl::SaveUserImageFromProfileImage() { | 646 void UserImageManagerImpl::SaveUserImageFromProfileImage() { |
| 643 if (IsUserImageManaged()) | 647 if (IsUserImageManaged()) |
| 644 return; | 648 return; |
| 645 // Use the profile image if it has been downloaded already. Otherwise, use a | 649 // Use the profile image if it has been downloaded already. Otherwise, use a |
| 646 // stub image (gray avatar). | 650 // stub image (gray avatar). |
| 647 job_.reset(new Job(this)); | 651 job_.reset(new Job(this)); |
| 648 job_->SetToImage(User::kProfileImageIndex, | 652 job_->SetToImage(User::kProfileImageIndex, |
| 649 downloaded_profile_image_.isNull() ? | 653 downloaded_profile_image_.isNull() |
| 650 UserImage() : | 654 ? user_manager::UserImage() |
| 651 UserImage::CreateAndEncode(downloaded_profile_image_)); | 655 : user_manager::UserImage::CreateAndEncode( |
| 656 downloaded_profile_image_)); |
| 652 // If no profile image has been downloaded yet, ensure that a download is | 657 // If no profile image has been downloaded yet, ensure that a download is |
| 653 // started. | 658 // started. |
| 654 if (downloaded_profile_image_.isNull()) | 659 if (downloaded_profile_image_.isNull()) |
| 655 DownloadProfileData(kProfileDownloadReasonProfileImageChosen); | 660 DownloadProfileData(kProfileDownloadReasonProfileImageChosen); |
| 656 } | 661 } |
| 657 | 662 |
| 658 void UserImageManagerImpl::DeleteUserImage() { | 663 void UserImageManagerImpl::DeleteUserImage() { |
| 659 job_.reset(); | 664 job_.reset(); |
| 660 DeleteUserImageAndLocalStateEntry(kUserImages); | 665 DeleteUserImageAndLocalStateEntry(kUserImages); |
| 661 DeleteUserImageAndLocalStateEntry(kUserImageProperties); | 666 DeleteUserImageAndLocalStateEntry(kUserImageProperties); |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 | 1002 |
| 998 bool UserImageManagerImpl::IsUserLoggedInAndRegular() const { | 1003 bool UserImageManagerImpl::IsUserLoggedInAndRegular() const { |
| 999 const User* user = GetUser(); | 1004 const User* user = GetUser(); |
| 1000 if (!user) | 1005 if (!user) |
| 1001 return false; | 1006 return false; |
| 1002 return user->is_logged_in() && | 1007 return user->is_logged_in() && |
| 1003 user->GetType() == user_manager::USER_TYPE_REGULAR; | 1008 user->GetType() == user_manager::USER_TYPE_REGULAR; |
| 1004 } | 1009 } |
| 1005 | 1010 |
| 1006 } // namespace chromeos | 1011 } // namespace chromeos |
| OLD | NEW |