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