Home | History | Annotate | Download | only in login
      1 // Copyright (c) 2013 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/chromeos/login/user_image_screen_handler.h"
      6 
      7 #include "ash/audio/sounds.h"
      8 #include "base/command_line.h"
      9 #include "base/logging.h"
     10 #include "base/metrics/histogram.h"
     11 #include "base/values.h"
     12 #include "chrome/browser/chromeos/login/existing_user_controller.h"
     13 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
     14 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
     15 #include "chrome/common/chrome_switches.h"
     16 #include "chrome/common/url_constants.h"
     17 #include "chrome/grit/generated_resources.h"
     18 #include "chromeos/audio/chromeos_sounds.h"
     19 #include "components/user_manager/user.h"
     20 #include "components/user_manager/user_image/default_user_images.h"
     21 #include "grit/browser_resources.h"
     22 #include "net/base/data_url.h"
     23 #include "ui/base/l10n/l10n_util.h"
     24 #include "ui/base/resource/resource_bundle.h"
     25 #include "url/gurl.h"
     26 
     27 namespace {
     28 
     29 const char kJsScreenPath[] = "login.UserImageScreen";
     30 
     31 }  // namespace
     32 
     33 namespace chromeos {
     34 
     35 UserImageScreenHandler::UserImageScreenHandler()
     36     : BaseScreenHandler(kJsScreenPath),
     37       screen_(NULL),
     38       show_on_init_(false),
     39       is_ready_(false) {
     40   ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
     41   media::SoundsManager* manager = media::SoundsManager::Get();
     42   manager->Initialize(SOUND_OBJECT_DELETE,
     43                       bundle.GetRawDataResource(IDR_SOUND_OBJECT_DELETE_WAV));
     44   manager->Initialize(SOUND_CAMERA_SNAP,
     45                       bundle.GetRawDataResource(IDR_SOUND_CAMERA_SNAP_WAV));
     46 }
     47 
     48 UserImageScreenHandler::~UserImageScreenHandler() {
     49   if (screen_) {
     50     screen_->OnActorDestroyed(this);
     51   }
     52 }
     53 
     54 void UserImageScreenHandler::Initialize() {
     55   if (show_on_init_) {
     56     Show();
     57     show_on_init_ = false;
     58   }
     59 }
     60 
     61 void UserImageScreenHandler::SetDelegate(
     62     UserImageScreenActor::Delegate* screen) {
     63   screen_ = screen;
     64 }
     65 
     66 void UserImageScreenHandler::Show() {
     67   if (!page_is_ready()) {
     68     show_on_init_ = true;
     69     return;
     70   }
     71   screen_show_time_ = base::Time::Now();
     72   ShowScreen(OobeUI::kScreenUserImagePicker, NULL);
     73 
     74   // When shown, query camera presence.
     75   if (!screen_)
     76     return;
     77   if (is_ready_)
     78     screen_->OnScreenReady();
     79 }
     80 
     81 void UserImageScreenHandler::Hide() {
     82 }
     83 
     84 void UserImageScreenHandler::PrepareToShow() {
     85 }
     86 
     87 void UserImageScreenHandler::DeclareLocalizedValues(
     88     LocalizedValuesBuilder* builder) {
     89   builder->Add("userImageScreenTitle", IDS_USER_IMAGE_SCREEN_TITLE);
     90   builder->Add("userImageScreenDescription",
     91                IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT);
     92   builder->Add("takePhoto", IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO);
     93   builder->Add("discardPhoto", IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO);
     94   builder->Add("flipPhoto", IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO);
     95   builder->Add("profilePhoto", IDS_IMAGE_SCREEN_PROFILE_PHOTO);
     96   builder->Add("profilePhotoLoading",
     97                IDS_IMAGE_SCREEN_PROFILE_LOADING_PHOTO);
     98   builder->Add("okButtonText", IDS_OK);
     99   builder->Add("authorCredit", IDS_OPTIONS_SET_WALLPAPER_AUTHOR_TEXT);
    100   builder->Add("photoFromCamera", IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA);
    101   builder->Add("photoFlippedAccessibleText",
    102                IDS_OPTIONS_PHOTO_FLIP_ACCESSIBLE_TEXT);
    103   builder->Add("photoFlippedBackAccessibleText",
    104                IDS_OPTIONS_PHOTO_FLIPBACK_ACCESSIBLE_TEXT);
    105   builder->Add("photoCaptureAccessibleText",
    106                IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT);
    107   builder->Add("photoDiscardAccessibleText",
    108                IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT);
    109   builder->Add("syncingPreferences", IDS_IMAGE_SCREEN_SYNCING_PREFERENCES);
    110 }
    111 
    112 void UserImageScreenHandler::RegisterMessages() {
    113   AddCallback("getImages", &UserImageScreenHandler::HandleGetImages);
    114   AddCallback("screenReady", &UserImageScreenHandler::HandleScreenReady);
    115   AddCallback("takePhoto", &UserImageScreenHandler::HandleTakePhoto);
    116   AddCallback("discardPhoto", &UserImageScreenHandler::HandleDiscardPhoto);
    117   AddCallback("photoTaken", &UserImageScreenHandler::HandlePhotoTaken);
    118   AddCallback("selectImage", &UserImageScreenHandler::HandleSelectImage);
    119   AddCallback("onUserImageAccepted",
    120               &UserImageScreenHandler::HandleImageAccepted);
    121   AddCallback("onUserImageScreenShown",
    122               &UserImageScreenHandler::HandleScreenShown);
    123 }
    124 
    125 void UserImageScreenHandler::SelectImage(int index) {
    126   if (page_is_ready())
    127     CallJS("setSelectedImage", user_manager::GetDefaultImageUrl(index));
    128 }
    129 
    130 void UserImageScreenHandler::SendProfileImage(const std::string& data_url) {
    131   if (page_is_ready())
    132     CallJS("setProfileImage", data_url);
    133 }
    134 
    135 void UserImageScreenHandler::OnProfileImageAbsent() {
    136   if (page_is_ready()) {
    137     scoped_ptr<base::Value> null_value(base::Value::CreateNullValue());
    138     CallJS("setProfileImage", *null_value);
    139   }
    140 }
    141 
    142 // TODO(antrim) : It looks more like parameters for "Init" rather than callback.
    143 void UserImageScreenHandler::HandleGetImages() {
    144   base::ListValue image_urls;
    145   for (int i = user_manager::kFirstDefaultImageIndex;
    146        i < user_manager::kDefaultImagesCount;
    147        ++i) {
    148     scoped_ptr<base::DictionaryValue> image_data(new base::DictionaryValue);
    149     image_data->SetString("url", user_manager::GetDefaultImageUrl(i));
    150     image_data->SetString(
    151         "author",
    152         l10n_util::GetStringUTF16(user_manager::kDefaultImageAuthorIDs[i]));
    153     image_data->SetString(
    154         "website",
    155         l10n_util::GetStringUTF16(user_manager::kDefaultImageWebsiteIDs[i]));
    156     image_data->SetString("title", user_manager::GetDefaultImageDescription(i));
    157     image_urls.Append(image_data.release());
    158   }
    159   CallJS("setDefaultImages", image_urls);
    160   if (!screen_)
    161     return;
    162   if (screen_->selected_image() != user_manager::User::USER_IMAGE_INVALID)
    163     SelectImage(screen_->selected_image());
    164 
    165   if (screen_->profile_picture_data_url() != url::kAboutBlankURL)
    166     SendProfileImage(screen_->profile_picture_data_url());
    167   else if (screen_->profile_picture_absent())
    168     OnProfileImageAbsent();
    169 }
    170 
    171 void UserImageScreenHandler::HandleScreenReady() {
    172   is_ready_ = true;
    173   if (screen_)
    174     screen_->OnScreenReady();
    175 }
    176 
    177 void UserImageScreenHandler::HandlePhotoTaken(const std::string& image_url) {
    178   std::string mime_type, charset, raw_data;
    179   if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data))
    180     NOTREACHED();
    181   DCHECK_EQ("image/png", mime_type);
    182 
    183   if (screen_)
    184     screen_->OnPhotoTaken(raw_data);
    185 }
    186 
    187 void UserImageScreenHandler::HandleTakePhoto() {
    188   ash::PlaySystemSoundIfSpokenFeedback(SOUND_CAMERA_SNAP);
    189 }
    190 
    191 void UserImageScreenHandler::HandleDiscardPhoto() {
    192   ash::PlaySystemSoundIfSpokenFeedback(SOUND_OBJECT_DELETE);
    193 }
    194 
    195 void UserImageScreenHandler::HandleSelectImage(const std::string& image_url,
    196                                                const std::string& image_type,
    197                                                bool is_user_selection) {
    198   if (screen_)
    199     screen_->OnImageSelected(image_type, image_url, is_user_selection);
    200 }
    201 
    202 void UserImageScreenHandler::HandleImageAccepted() {
    203   if (screen_)
    204     screen_->OnImageAccepted();
    205 }
    206 
    207 void UserImageScreenHandler::HandleScreenShown() {
    208   DCHECK(!screen_show_time_.is_null());
    209 
    210   base::TimeDelta delta = base::Time::Now() - screen_show_time_;
    211   VLOG(1) << "Screen load time: " << delta.InSecondsF();
    212   UMA_HISTOGRAM_TIMES("UserImage.ScreenIsShownTime", delta);
    213 }
    214 
    215 void UserImageScreenHandler::SetCameraPresent(bool present) {
    216   CallJS("setCameraPresent", present);
    217 }
    218 
    219 void UserImageScreenHandler::HideCurtain() {
    220   CallJS("hideCurtain");
    221 }
    222 
    223 }  // namespace chromeos
    224