user_image_source.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/browser/chromeos/login/default_user_images.h" 11#include "chrome/browser/chromeos/login/user_manager.h" 12#include "chrome/common/url_constants.h" 13#include "grit/theme_resources.h" 14#include "net/base/escape.h" 15#include "ui/base/resource/resource_bundle.h" 16#include "ui/gfx/codec/png_codec.h" 17#include "url/url_parse.h" 18 19namespace { 20 21// Animated key is used in user image URL requests to specify that 22// animated version of user image is required. Without that key 23// non-animated version of user image should be returned. 24const char kKeyAnimated[] = "animated"; 25 26// Parses the user image URL, which looks like 27// "chrome://userimage/user@host?key1=value1&...&key_n=value_n", 28// to user email and optional parameters. 29void ParseRequest(const GURL& url, 30 std::string* email, 31 bool* is_image_animated) { 32 DCHECK(url.is_valid()); 33 *email = net::UnescapeURLComponent(url.path().substr(1), 34 (net::UnescapeRule::URL_SPECIAL_CHARS | 35 net::UnescapeRule::SPACES)); 36 std::string url_spec = url.possibly_invalid_spec(); 37 url_parse::Component query = url.parsed_for_possibly_invalid_spec().query; 38 url_parse::Component key, value; 39 *is_image_animated = false; 40 while (ExtractQueryKeyValue(url_spec.c_str(), &query, &key, &value)) { 41 if (url_spec.substr(key.begin, key.len) == kKeyAnimated) { 42 *is_image_animated = true; 43 break; 44 } 45 } 46} 47 48} // namespace 49 50namespace chromeos { 51namespace options { 52 53base::RefCountedMemory* UserImageSource::GetUserImage( 54 const std::string& email, 55 bool is_image_animated, 56 ui::ScaleFactor scale_factor) const { 57 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(email); 58 if (user) { 59 if (user->has_animated_image() && is_image_animated) { 60 return new base::RefCountedBytes(user->animated_image()); 61 } else if (user->has_raw_image()) { 62 return new base::RefCountedBytes(user->raw_image()); 63 } else if (user->image_is_stub()) { 64 return ResourceBundle::GetSharedInstance(). 65 LoadDataResourceBytesForScale(IDR_PROFILE_PICTURE_LOADING, 66 scale_factor); 67 } else if (user->HasDefaultImage()) { 68 return ResourceBundle::GetSharedInstance(). 69 LoadDataResourceBytesForScale( 70 kDefaultImageResourceIDs[user->image_index()], 71 scale_factor); 72 } else { 73 NOTREACHED() << "User with custom image missing raw data"; 74 } 75 } 76 return ResourceBundle::GetSharedInstance(). 77 LoadDataResourceBytesForScale(IDR_LOGIN_DEFAULT_USER, scale_factor); 78} 79 80UserImageSource::UserImageSource() { 81} 82 83UserImageSource::~UserImageSource() {} 84 85std::string UserImageSource::GetSource() const { 86 return chrome::kChromeUIUserImageHost; 87} 88 89void UserImageSource::StartDataRequest( 90 const std::string& path, 91 int render_process_id, 92 int render_frame_id, 93 const content::URLDataSource::GotDataCallback& callback) { 94 std::string email; 95 bool is_image_animated = false; 96 GURL url(chrome::kChromeUIUserImageURL + path); 97 ParseRequest(url, &email, &is_image_animated); 98 callback.Run(GetUserImage(email, is_image_animated, ui::SCALE_FACTOR_100P)); 99} 100 101std::string UserImageSource::GetMimeType(const std::string& path) const { 102 // We need to explicitly return a mime type, otherwise if the user tries to 103 // drag the image they get no extension. 104 std::string email; 105 bool is_image_animated = false; 106 107 GURL url(chrome::kChromeUIUserImageURL + path); 108 ParseRequest(url, &email, &is_image_animated); 109 110 if (is_image_animated) { 111 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(email); 112 if (user && user->has_animated_image()) 113 return "image/gif"; 114 } 115 return "image/png"; 116} 117 118} // namespace options 119} // namespace chromeos 120