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/ui/webui/options/chromeos/user_image_source.h"
6
7#include "base/memory/ref_counted_memory.h"
8#include "base/message_loop/message_loop.h"
9#include "base/strings/string_split.h"
10#include "chrome/common/url_constants.h"
11#include "components/user_manager/user_image/default_user_images.h"
12#include "components/user_manager/user_manager.h"
13#include "grit/theme_resources.h"
14#include "grit/ui_chromeos_resources.h"
15#include "net/base/escape.h"
16#include "ui/base/resource/resource_bundle.h"
17#include "ui/gfx/codec/png_codec.h"
18#include "url/url_parse.h"
19
20namespace {
21
22// Parses the user image URL, which looks like
23// "chrome://userimage/user@host?key1=value1&...&key_n=value_n",
24// to user email.
25void ParseRequest(const GURL& url,
26                  std::string* email) {
27  DCHECK(url.is_valid());
28  *email = net::UnescapeURLComponent(url.path().substr(1),
29                                    (net::UnescapeRule::URL_SPECIAL_CHARS |
30                                     net::UnescapeRule::SPACES));
31}
32
33}  // namespace
34
35namespace chromeos {
36namespace options {
37
38base::RefCountedMemory* UserImageSource::GetUserImage(
39    const std::string& email,
40    ui::ScaleFactor scale_factor) const {
41  const user_manager::User* user =
42      user_manager::UserManager::Get()->FindUser(email);
43  if (user) {
44    if (user->has_raw_image()) {
45      return new base::RefCountedBytes(user->raw_image());
46    } else if (user->image_is_stub()) {
47      return ResourceBundle::GetSharedInstance().
48          LoadDataResourceBytesForScale(IDR_PROFILE_PICTURE_LOADING,
49                                        scale_factor);
50    } else if (user->HasDefaultImage()) {
51      return ResourceBundle::GetSharedInstance().
52          LoadDataResourceBytesForScale(
53              user_manager::kDefaultImageResourceIDs[user->image_index()],
54              scale_factor);
55    } else {
56      NOTREACHED() << "User with custom image missing raw data";
57    }
58  }
59  return ResourceBundle::GetSharedInstance().
60      LoadDataResourceBytesForScale(IDR_LOGIN_DEFAULT_USER, scale_factor);
61}
62
63UserImageSource::UserImageSource() {
64}
65
66UserImageSource::~UserImageSource() {}
67
68std::string UserImageSource::GetSource() const {
69  return chrome::kChromeUIUserImageHost;
70}
71
72void UserImageSource::StartDataRequest(
73    const std::string& path,
74    int render_process_id,
75    int render_frame_id,
76    const content::URLDataSource::GotDataCallback& callback) {
77  std::string email;
78  GURL url(chrome::kChromeUIUserImageURL + path);
79  ParseRequest(url, &email);
80  callback.Run(GetUserImage(email, ui::SCALE_FACTOR_100P));
81}
82
83std::string UserImageSource::GetMimeType(const std::string& path) const {
84  // We need to explicitly return a mime type, otherwise if the user tries to
85  // drag the image they get no extension.
86  return "image/png";
87}
88
89}  // namespace options
90}  // namespace chromeos
91