Home | History | Annotate | Download | only in managed
      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/chromeos/login/managed/locally_managed_user_creation_screen.h"
      6 
      7 #include "ash/desktop_background/desktop_background_controller.h"
      8 #include "ash/shell.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/chromeos/camera_detector.h"
     11 #include "chrome/browser/chromeos/login/existing_user_controller.h"
     12 #include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_controller.h"
     13 #include "chrome/browser/chromeos/login/screens/error_screen.h"
     14 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
     15 #include "chrome/browser/chromeos/login/user_image.h"
     16 #include "chrome/browser/chromeos/login/user_image_manager.h"
     17 #include "chrome/browser/chromeos/login/wizard_controller.h"
     18 #include "chromeos/network/network_state.h"
     19 #include "content/public/browser/browser_thread.h"
     20 #include "grit/generated_resources.h"
     21 #include "third_party/skia/include/core/SkBitmap.h"
     22 #include "ui/base/l10n/l10n_util.h"
     23 #include "ui/gfx/image/image_skia.h"
     24 
     25 namespace chromeos {
     26 
     27 namespace {
     28 
     29 void ConfigureErrorScreen(ErrorScreen* screen,
     30     const NetworkState* network,
     31     const NetworkPortalDetector::CaptivePortalStatus status) {
     32   switch (status) {
     33     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN:
     34     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
     35       NOTREACHED();
     36       break;
     37     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
     38       screen->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE,
     39                             std::string());
     40       break;
     41     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
     42       screen->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL,
     43                             network->name());
     44       screen->FixCaptivePortal();
     45       break;
     46     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
     47       screen->SetErrorState(ErrorScreen::ERROR_STATE_PROXY,
     48                             std::string());
     49       break;
     50     default:
     51       NOTREACHED();
     52       break;
     53   }
     54 }
     55 
     56 } // namespace
     57 
     58 LocallyManagedUserCreationScreen::LocallyManagedUserCreationScreen(
     59     ScreenObserver* observer,
     60     LocallyManagedUserCreationScreenHandler* actor)
     61     : WizardScreen(observer),
     62       weak_factory_(this),
     63       actor_(actor),
     64       on_error_screen_(false),
     65       on_image_screen_(false),
     66       image_decoder_(NULL),
     67       apply_photo_after_decoding_(false),
     68       selected_image_(0) {
     69   DCHECK(actor_);
     70   if (actor_)
     71     actor_->SetDelegate(this);
     72 }
     73 
     74 LocallyManagedUserCreationScreen::~LocallyManagedUserCreationScreen() {
     75   if (actor_)
     76     actor_->SetDelegate(NULL);
     77   if (image_decoder_.get())
     78     image_decoder_->set_delegate(NULL);
     79 }
     80 
     81 void LocallyManagedUserCreationScreen::PrepareToShow() {
     82   if (actor_)
     83     actor_->PrepareToShow();
     84 }
     85 
     86 void LocallyManagedUserCreationScreen::Show() {
     87   if (actor_) {
     88     actor_->Show();
     89     // TODO(antrim) : temorary hack (until upcoming hackaton). Should be
     90     // removed once we have screens reworked.
     91     if (on_image_screen_)
     92       actor_->ShowTutorialPage();
     93     else
     94       actor_->ShowIntroPage();
     95   }
     96 
     97   NetworkPortalDetector* detector = NetworkPortalDetector::GetInstance();
     98   if (detector && !on_error_screen_)
     99     detector->AddAndFireObserver(this);
    100   on_error_screen_ = false;
    101 }
    102 
    103 void LocallyManagedUserCreationScreen::OnPortalDetectionCompleted(
    104     const NetworkState* network,
    105     const NetworkPortalDetector::CaptivePortalState& state)  {
    106   if (state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) {
    107     get_screen_observer()->HideErrorScreen(this);
    108   } else {
    109     on_error_screen_ = true;
    110     ErrorScreen* screen = get_screen_observer()->GetErrorScreen();
    111     ConfigureErrorScreen(screen, network, state.status);
    112     screen->SetUIState(ErrorScreen::UI_STATE_LOCALLY_MANAGED);
    113     get_screen_observer()->ShowErrorScreen();
    114   }
    115 }
    116 
    117 void LocallyManagedUserCreationScreen::
    118     ShowManagerInconsistentStateErrorScreen() {
    119   if (!actor_)
    120     return;
    121   actor_->ShowErrorPage(
    122       l10n_util::GetStringUTF16(
    123           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE_TITLE),
    124       l10n_util::GetStringUTF16(
    125           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE),
    126       l10n_util::GetStringUTF16(
    127           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE_BUTTON));
    128 }
    129 
    130 void LocallyManagedUserCreationScreen::ShowInitialScreen() {
    131   if (actor_)
    132     actor_->ShowIntroPage();
    133 }
    134 
    135 void LocallyManagedUserCreationScreen::Hide() {
    136   if (actor_)
    137     actor_->Hide();
    138   NetworkPortalDetector* detector = NetworkPortalDetector::GetInstance();
    139   if (detector && !on_error_screen_)
    140     detector->RemoveObserver(this);
    141 }
    142 
    143 std::string LocallyManagedUserCreationScreen::GetName() const {
    144   return WizardController::kLocallyManagedUserCreationScreenName;
    145 }
    146 
    147 void LocallyManagedUserCreationScreen::AbortFlow() {
    148   controller_->CancelCreation();
    149 }
    150 
    151 void LocallyManagedUserCreationScreen::FinishFlow() {
    152   controller_->FinishCreation();
    153 }
    154 
    155 void LocallyManagedUserCreationScreen::AuthenticateManager(
    156     const std::string& manager_id,
    157     const std::string& manager_password) {
    158   // Make sure no two controllers exist at the same time.
    159   controller_.reset();
    160   controller_.reset(new LocallyManagedUserCreationController(this, manager_id));
    161 
    162   ExistingUserController::current_controller()->
    163       Login(UserContext(manager_id,
    164                         manager_password,
    165                         std::string()  /* auth_code */));
    166 }
    167 
    168 void LocallyManagedUserCreationScreen::CreateManagedUser(
    169     const string16& display_name,
    170     const std::string& managed_user_password) {
    171   DCHECK(controller_.get());
    172   controller_->SetUpCreation(display_name, managed_user_password);
    173   controller_->StartCreation();
    174 }
    175 
    176 void LocallyManagedUserCreationScreen::OnManagerLoginFailure() {
    177   if (actor_)
    178     actor_->ShowManagerPasswordError();
    179 }
    180 
    181 void LocallyManagedUserCreationScreen::OnManagerFullyAuthenticated(
    182     Profile* manager_profile) {
    183   DCHECK(controller_.get());
    184   // For manager user, move desktop to locked container so that windows created
    185   // during the user image picker step are below it.
    186   ash::Shell::GetInstance()->
    187       desktop_background_controller()->MoveDesktopToLockedContainer();
    188 
    189   controller_->SetManagerProfile(manager_profile);
    190   if (actor_)
    191     actor_->ShowUsernamePage();
    192 }
    193 
    194 void LocallyManagedUserCreationScreen::OnManagerCryptohomeAuthenticated() {
    195   if (actor_) {
    196     actor_->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
    197             IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_AUTH_PROGRESS_MESSAGE));
    198   }
    199 }
    200 
    201 void LocallyManagedUserCreationScreen::OnExit() {}
    202 
    203 void LocallyManagedUserCreationScreen::OnActorDestroyed(
    204     LocallyManagedUserCreationScreenHandler* actor) {
    205   if (actor_ == actor)
    206     actor_ = NULL;
    207 }
    208 
    209 void LocallyManagedUserCreationScreen::OnCreationError(
    210     LocallyManagedUserCreationController::ErrorCode code) {
    211   string16 title;
    212   string16 message;
    213   string16 button;
    214   // TODO(antrim) : find out which errors do we really have.
    215   // We might reuse some error messages from ordinary user flow.
    216   switch (code) {
    217     case LocallyManagedUserCreationController::CRYPTOHOME_NO_MOUNT:
    218     case LocallyManagedUserCreationController::CRYPTOHOME_FAILED_MOUNT:
    219     case LocallyManagedUserCreationController::CRYPTOHOME_FAILED_TPM:
    220       title = l10n_util::GetStringUTF16(
    221           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR_TITLE);
    222       message = l10n_util::GetStringUTF16(
    223           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR);
    224       button = l10n_util::GetStringUTF16(
    225           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR_BUTTON);
    226       break;
    227     case LocallyManagedUserCreationController::CLOUD_SERVER_ERROR:
    228     case LocallyManagedUserCreationController::TOKEN_WRITE_FAILED:
    229       title = l10n_util::GetStringUTF16(
    230           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE);
    231       message = l10n_util::GetStringUTF16(
    232           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR);
    233       button = l10n_util::GetStringUTF16(
    234           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON);
    235       break;
    236     case LocallyManagedUserCreationController::NO_ERROR:
    237       NOTREACHED();
    238   }
    239   if (actor_)
    240     actor_->ShowErrorPage(title, message, button);
    241 }
    242 
    243 void LocallyManagedUserCreationScreen::OnCreationTimeout() {
    244   if (actor_) {
    245     actor_->ShowStatusMessage(false /* error */, l10n_util::GetStringUTF16(
    246         IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_CREATION_TIMEOUT_MESSAGE));
    247   }
    248 }
    249 
    250 // TODO(antrim) : this is an explicit code duplications with UserImageScreen.
    251 // It should be removed by issue 251179.
    252 
    253 void LocallyManagedUserCreationScreen::ApplyPicture() {
    254   UserManager* user_manager = UserManager::Get();
    255   UserImageManager* image_manager = user_manager->GetUserImageManager();
    256   std::string user_id = controller_->GetManagedUserId();
    257   switch (selected_image_) {
    258     case User::kExternalImageIndex:
    259       // Photo decoding may not have been finished yet.
    260       if (user_photo_.isNull()) {
    261         apply_photo_after_decoding_ = true;
    262         return;
    263       }
    264       image_manager->
    265           SaveUserImage(user_id, UserImage::CreateAndEncode(user_photo_));
    266       break;
    267     case User::kProfileImageIndex:
    268       NOTREACHED() << "Supervised users have no profile pictures";
    269       break;
    270     default:
    271       DCHECK(selected_image_ >= 0 && selected_image_ < kDefaultImagesCount);
    272       image_manager->SaveUserDefaultImageIndex(user_id, selected_image_);
    273       break;
    274   }
    275   // Proceed to tutorial.
    276   actor_->ShowTutorialPage();
    277 }
    278 
    279 void LocallyManagedUserCreationScreen::OnCreationSuccess() {
    280   ApplyPicture();
    281 }
    282 
    283 void LocallyManagedUserCreationScreen::CheckCameraPresence() {
    284   CameraDetector::StartPresenceCheck(
    285       base::Bind(&LocallyManagedUserCreationScreen::OnCameraPresenceCheckDone,
    286                  weak_factory_.GetWeakPtr()));
    287 }
    288 
    289 void LocallyManagedUserCreationScreen::OnCameraPresenceCheckDone() {
    290   if (actor_) {
    291     actor_->SetCameraPresent(
    292         CameraDetector::camera_presence() == CameraDetector::kCameraPresent);
    293   }
    294 }
    295 
    296 void LocallyManagedUserCreationScreen::OnPhotoTaken(
    297     const std::string& raw_data) {
    298   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    299   user_photo_ = gfx::ImageSkia();
    300   if (image_decoder_.get())
    301     image_decoder_->set_delegate(NULL);
    302   image_decoder_ = new ImageDecoder(this, raw_data,
    303                                     ImageDecoder::DEFAULT_CODEC);
    304   scoped_refptr<base::MessageLoopProxy> task_runner =
    305       content::BrowserThread::GetMessageLoopProxyForThread(
    306           content::BrowserThread::UI);
    307   image_decoder_->Start(task_runner);
    308 }
    309 
    310 void LocallyManagedUserCreationScreen::OnImageDecoded(
    311     const ImageDecoder* decoder,
    312     const SkBitmap& decoded_image) {
    313   DCHECK_EQ(image_decoder_.get(), decoder);
    314   user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image);
    315   if (apply_photo_after_decoding_)
    316     ApplyPicture();
    317 }
    318 
    319 void LocallyManagedUserCreationScreen::OnDecodeImageFailed(
    320     const ImageDecoder* decoder) {
    321   NOTREACHED() << "Failed to decode PNG image from WebUI";
    322 }
    323 
    324 void LocallyManagedUserCreationScreen::OnImageSelected(
    325     const std::string& image_type,
    326     const std::string& image_url) {
    327   if (image_url.empty())
    328     return;
    329   int user_image_index = User::kInvalidImageIndex;
    330   if (image_type == "default" &&
    331       IsDefaultImageUrl(image_url, &user_image_index)) {
    332     selected_image_ = user_image_index;
    333   } else if (image_type == "camera") {
    334     selected_image_ = User::kExternalImageIndex;
    335   } else {
    336     NOTREACHED() << "Unexpected image type: " << image_type;
    337   }
    338 }
    339 
    340 void LocallyManagedUserCreationScreen::OnImageAccepted() {
    341 }
    342 
    343 }  // namespace chromeos
    344