Home | History | Annotate | Download | only in login
      1 // Copyright 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/app_launch_splash_screen_handler.h"
      6 
      7 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
      8 #include "chrome/browser/chromeos/login/screens/error_screen_actor.h"
      9 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
     10 #include "chrome/grit/chromium_strings.h"
     11 #include "chrome/grit/generated_resources.h"
     12 #include "chromeos/network/network_state.h"
     13 #include "chromeos/network/network_state_handler.h"
     14 #include "grit/chrome_unscaled_resources.h"
     15 #include "ui/base/l10n/l10n_util.h"
     16 #include "ui/base/resource/resource_bundle.h"
     17 #include "ui/base/webui/web_ui_util.h"
     18 
     19 namespace {
     20 
     21 const char kJsScreenPath[] = "login.AppLaunchSplashScreen";
     22 
     23 // Returns network name by service path.
     24 std::string GetNetworkName(const std::string& service_path) {
     25   const chromeos::NetworkState* network =
     26       chromeos::NetworkHandler::Get()->network_state_handler()->GetNetworkState(
     27           service_path);
     28   if (!network)
     29     return std::string();
     30   return network->name();
     31 }
     32 
     33 }  // namespace
     34 
     35 namespace chromeos {
     36 
     37 AppLaunchSplashScreenHandler::AppLaunchSplashScreenHandler(
     38       const scoped_refptr<NetworkStateInformer>& network_state_informer,
     39       ErrorScreenActor* error_screen_actor)
     40     : BaseScreenHandler(kJsScreenPath),
     41       delegate_(NULL),
     42       show_on_init_(false),
     43       state_(APP_LAUNCH_STATE_LOADING_AUTH_FILE),
     44       network_state_informer_(network_state_informer),
     45       error_screen_actor_(error_screen_actor),
     46       online_state_(false),
     47       network_config_done_(false),
     48       network_config_requested_(false) {
     49   network_state_informer_->AddObserver(this);
     50 }
     51 
     52 AppLaunchSplashScreenHandler::~AppLaunchSplashScreenHandler() {
     53   network_state_informer_->RemoveObserver(this);
     54 }
     55 
     56 void AppLaunchSplashScreenHandler::DeclareLocalizedValues(
     57     LocalizedValuesBuilder* builder) {
     58 
     59   builder->Add("appStartMessage", IDS_APP_START_NETWORK_WAIT_MESSAGE);
     60   builder->Add("configureNetwork", IDS_APP_START_CONFIGURE_NETWORK);
     61 
     62   const base::string16 product_os_name =
     63       l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME);
     64   builder->Add(
     65       "shortcutInfo",
     66       l10n_util::GetStringFUTF16(IDS_APP_START_BAILOUT_SHORTCUT_FORMAT,
     67                                  product_os_name));
     68 
     69   builder->Add(
     70       "productName",
     71       l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME));
     72 }
     73 
     74 void AppLaunchSplashScreenHandler::Initialize() {
     75   if (show_on_init_) {
     76     show_on_init_ = false;
     77     Show(app_id_);
     78   }
     79 }
     80 
     81 void AppLaunchSplashScreenHandler::Show(const std::string& app_id) {
     82   app_id_ = app_id;
     83   if (!page_is_ready()) {
     84     show_on_init_ = true;
     85     return;
     86   }
     87 
     88   base::DictionaryValue data;
     89   data.SetBoolean("shortcutEnabled",
     90                   !KioskAppManager::Get()->GetDisableBailoutShortcut());
     91 
     92   // |data| will take ownership of |app_info|.
     93   base::DictionaryValue *app_info = new base::DictionaryValue();
     94   PopulateAppInfo(app_info);
     95   data.Set("appInfo", app_info);
     96 
     97   SetLaunchText(l10n_util::GetStringUTF8(GetProgressMessageFromState(state_)));
     98   ShowScreen(OobeUI::kScreenAppLaunchSplash, &data);
     99 }
    100 
    101 void AppLaunchSplashScreenHandler::RegisterMessages() {
    102   AddCallback("configureNetwork",
    103               &AppLaunchSplashScreenHandler::HandleConfigureNetwork);
    104   AddCallback("cancelAppLaunch",
    105               &AppLaunchSplashScreenHandler::HandleCancelAppLaunch);
    106   AddCallback("continueAppLaunch",
    107               &AppLaunchSplashScreenHandler::HandleContinueAppLaunch);
    108   AddCallback("networkConfigRequest",
    109               &AppLaunchSplashScreenHandler::HandleNetworkConfigRequested);
    110 }
    111 
    112 void AppLaunchSplashScreenHandler::PrepareToShow() {
    113 }
    114 
    115 void AppLaunchSplashScreenHandler::Hide() {
    116 }
    117 
    118 void AppLaunchSplashScreenHandler::ToggleNetworkConfig(bool visible) {
    119   CallJS("toggleNetworkConfig", visible);
    120 }
    121 
    122 void AppLaunchSplashScreenHandler::UpdateAppLaunchState(AppLaunchState state) {
    123   if (state == state_)
    124     return;
    125 
    126   state_ = state;
    127   if (page_is_ready()) {
    128     SetLaunchText(
    129         l10n_util::GetStringUTF8(GetProgressMessageFromState(state_)));
    130   }
    131   UpdateState(ErrorScreenActor::ERROR_REASON_UPDATE);
    132 }
    133 
    134 void AppLaunchSplashScreenHandler::SetDelegate(
    135     AppLaunchSplashScreenHandler::Delegate* delegate) {
    136   delegate_ = delegate;
    137 }
    138 
    139 void AppLaunchSplashScreenHandler::ShowNetworkConfigureUI() {
    140   NetworkStateInformer::State state = network_state_informer_->state();
    141   if (state == NetworkStateInformer::ONLINE) {
    142     online_state_ = true;
    143     if (!network_config_requested_) {
    144       delegate_->OnNetworkStateChanged(true);
    145       return;
    146     }
    147   }
    148 
    149   const std::string network_path = network_state_informer_->network_path();
    150   const std::string network_name = GetNetworkName(network_path);
    151 
    152   error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_KIOSK_MODE);
    153   error_screen_actor_->AllowGuestSignin(false);
    154   error_screen_actor_->AllowOfflineLogin(false);
    155 
    156   switch (state) {
    157     case NetworkStateInformer::CAPTIVE_PORTAL: {
    158       error_screen_actor_->SetErrorState(
    159           ErrorScreen::ERROR_STATE_PORTAL, network_name);
    160       error_screen_actor_->FixCaptivePortal();
    161 
    162       break;
    163     }
    164     case NetworkStateInformer::PROXY_AUTH_REQUIRED: {
    165       error_screen_actor_->SetErrorState(
    166           ErrorScreen::ERROR_STATE_PROXY, network_name);
    167       break;
    168     }
    169     case NetworkStateInformer::OFFLINE: {
    170       error_screen_actor_->SetErrorState(
    171           ErrorScreen::ERROR_STATE_OFFLINE, network_name);
    172       break;
    173     }
    174     case NetworkStateInformer::ONLINE: {
    175       error_screen_actor_->SetErrorState(
    176           ErrorScreen::ERROR_STATE_KIOSK_ONLINE, network_name);
    177       break;
    178     }
    179     default:
    180       error_screen_actor_->SetErrorState(
    181           ErrorScreen::ERROR_STATE_OFFLINE, network_name);
    182       NOTREACHED();
    183       break;
    184   }
    185 
    186   OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
    187   OobeUI* oobe_ui = static_cast<OobeUI*>(web_ui()->GetController());
    188   if (oobe_ui)
    189     screen = oobe_ui->current_screen();
    190 
    191   if (screen != OobeUI::SCREEN_ERROR_MESSAGE)
    192     error_screen_actor_->Show(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH, NULL);
    193 }
    194 
    195 bool AppLaunchSplashScreenHandler::IsNetworkReady() {
    196   return network_state_informer_->state() == NetworkStateInformer::ONLINE;
    197 }
    198 
    199 void AppLaunchSplashScreenHandler::OnNetworkReady() {
    200   // Purposely leave blank because the online case is handled in UpdateState
    201   // call below.
    202 }
    203 
    204 void AppLaunchSplashScreenHandler::UpdateState(
    205     ErrorScreenActor::ErrorReason reason) {
    206   if (!delegate_ ||
    207       (state_ != APP_LAUNCH_STATE_PREPARING_NETWORK &&
    208        state_ != APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT)) {
    209     return;
    210   }
    211 
    212   bool new_online_state =
    213       network_state_informer_->state() == NetworkStateInformer::ONLINE;
    214   delegate_->OnNetworkStateChanged(new_online_state);
    215 
    216   online_state_ = new_online_state;
    217 }
    218 
    219 void AppLaunchSplashScreenHandler::PopulateAppInfo(
    220     base::DictionaryValue* out_info) {
    221   KioskAppManager::App app;
    222   KioskAppManager::Get()->GetApp(app_id_, &app);
    223 
    224   if (app.name.empty())
    225     app.name = l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME);
    226 
    227   if (app.icon.isNull()) {
    228     app.icon = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    229         IDR_PRODUCT_LOGO_128);
    230   }
    231 
    232   out_info->SetString("name", app.name);
    233   out_info->SetString("iconURL", webui::GetBitmapDataUrl(*app.icon.bitmap()));
    234 }
    235 
    236 void AppLaunchSplashScreenHandler::SetLaunchText(const std::string& text) {
    237   CallJS("updateMessage", text);
    238 }
    239 
    240 int AppLaunchSplashScreenHandler::GetProgressMessageFromState(
    241     AppLaunchState state) {
    242   switch (state) {
    243     case APP_LAUNCH_STATE_LOADING_AUTH_FILE:
    244     case APP_LAUNCH_STATE_LOADING_TOKEN_SERVICE:
    245       // TODO(zelidrag): Add better string for this one than "Please wait..."
    246       return IDS_SYNC_SETUP_SPINNER_TITLE;
    247     case APP_LAUNCH_STATE_PREPARING_NETWORK:
    248       return IDS_APP_START_NETWORK_WAIT_MESSAGE;
    249     case APP_LAUNCH_STATE_INSTALLING_APPLICATION:
    250       return IDS_APP_START_APP_WAIT_MESSAGE;
    251     case APP_LAUNCH_STATE_WAITING_APP_WINDOW:
    252       return IDS_APP_START_WAIT_FOR_APP_WINDOW_MESSAGE;
    253     case APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT:
    254       return IDS_APP_START_NETWORK_WAIT_TIMEOUT_MESSAGE;
    255   }
    256   return IDS_APP_START_NETWORK_WAIT_MESSAGE;
    257 }
    258 
    259 void AppLaunchSplashScreenHandler::HandleConfigureNetwork() {
    260   if (delegate_)
    261     delegate_->OnConfigureNetwork();
    262   else
    263     LOG(WARNING) << "No delegate set to handle network configuration.";
    264 }
    265 
    266 void AppLaunchSplashScreenHandler::HandleCancelAppLaunch() {
    267   if (delegate_)
    268     delegate_->OnCancelAppLaunch();
    269   else
    270     LOG(WARNING) << "No delegate set to handle cancel app launch";
    271 }
    272 
    273 void AppLaunchSplashScreenHandler::HandleNetworkConfigRequested() {
    274   if (!delegate_ || network_config_done_)
    275     return;
    276 
    277   network_config_requested_ = true;
    278   delegate_->OnNetworkConfigRequested(true);
    279 }
    280 
    281 void AppLaunchSplashScreenHandler::HandleContinueAppLaunch() {
    282   DCHECK(online_state_);
    283   if (delegate_ && online_state_) {
    284     network_config_requested_ = false;
    285     network_config_done_ = true;
    286     delegate_->OnNetworkConfigRequested(false);
    287     Show(app_id_);
    288   }
    289 }
    290 
    291 }  // namespace chromeos
    292