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   network_state_informer_->AddObserver(this);
     48 }
     49 
     50 AppLaunchSplashScreenHandler::~AppLaunchSplashScreenHandler() {
     51   network_state_informer_->RemoveObserver(this);
     52 }
     53 
     54 void AppLaunchSplashScreenHandler::DeclareLocalizedValues(
     55     LocalizedValuesBuilder* builder) {
     56 
     57   builder->Add("appStartMessage", IDS_APP_START_NETWORK_WAIT_MESSAGE);
     58   builder->Add("configureNetwork", IDS_APP_START_CONFIGURE_NETWORK);
     59 
     60   const base::string16 product_os_name =
     61       l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME);
     62   builder->Add(
     63       "shortcutInfo",
     64       l10n_util::GetStringFUTF16(IDS_APP_START_BAILOUT_SHORTCUT_FORMAT,
     65                                  product_os_name));
     66 
     67   builder->Add(
     68       "productName",
     69       l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME));
     70 }
     71 
     72 void AppLaunchSplashScreenHandler::Initialize() {
     73   if (show_on_init_) {
     74     show_on_init_ = false;
     75     Show(app_id_);
     76   }
     77 }
     78 
     79 void AppLaunchSplashScreenHandler::Show(const std::string& app_id) {
     80   app_id_ = app_id;
     81   if (!page_is_ready()) {
     82     show_on_init_ = true;
     83     return;
     84   }
     85 
     86   base::DictionaryValue data;
     87   data.SetBoolean("shortcutEnabled",
     88                   !KioskAppManager::Get()->GetDisableBailoutShortcut());
     89 
     90   // |data| will take ownership of |app_info|.
     91   base::DictionaryValue *app_info = new base::DictionaryValue();
     92   PopulateAppInfo(app_info);
     93   data.Set("appInfo", app_info);
     94 
     95   SetLaunchText(l10n_util::GetStringUTF8(GetProgressMessageFromState(state_)));
     96   ShowScreen(OobeUI::kScreenAppLaunchSplash, &data);
     97 }
     98 
     99 void AppLaunchSplashScreenHandler::RegisterMessages() {
    100   AddCallback("configureNetwork",
    101               &AppLaunchSplashScreenHandler::HandleConfigureNetwork);
    102   AddCallback("cancelAppLaunch",
    103               &AppLaunchSplashScreenHandler::HandleCancelAppLaunch);
    104 }
    105 
    106 void AppLaunchSplashScreenHandler::PrepareToShow() {
    107 }
    108 
    109 void AppLaunchSplashScreenHandler::Hide() {
    110 }
    111 
    112 void AppLaunchSplashScreenHandler::ToggleNetworkConfig(bool visible) {
    113   CallJS("toggleNetworkConfig", visible);
    114 }
    115 
    116 void AppLaunchSplashScreenHandler::UpdateAppLaunchState(AppLaunchState state) {
    117   if (state == state_)
    118     return;
    119 
    120   state_ = state;
    121   if (page_is_ready()) {
    122     SetLaunchText(
    123         l10n_util::GetStringUTF8(GetProgressMessageFromState(state_)));
    124   }
    125   UpdateState(ErrorScreenActor::ERROR_REASON_UPDATE);
    126 }
    127 
    128 void AppLaunchSplashScreenHandler::SetDelegate(
    129     AppLaunchSplashScreenHandler::Delegate* delegate) {
    130   delegate_ = delegate;
    131 }
    132 
    133 void AppLaunchSplashScreenHandler::ShowNetworkConfigureUI() {
    134   NetworkStateInformer::State state = network_state_informer_->state();
    135   if (state == NetworkStateInformer::ONLINE) {
    136     delegate_->OnNetworkStateChanged(true);
    137     return;
    138   }
    139 
    140   const std::string network_path = network_state_informer_->network_path();
    141   const std::string network_name = GetNetworkName(network_path);
    142 
    143   error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_KIOSK_MODE);
    144   error_screen_actor_->AllowGuestSignin(false);
    145   error_screen_actor_->AllowOfflineLogin(false);
    146 
    147   switch (state) {
    148     case NetworkStateInformer::CAPTIVE_PORTAL: {
    149       error_screen_actor_->SetErrorState(
    150           ErrorScreen::ERROR_STATE_PORTAL, network_name);
    151       error_screen_actor_->FixCaptivePortal();
    152 
    153       break;
    154     }
    155     case NetworkStateInformer::PROXY_AUTH_REQUIRED: {
    156       error_screen_actor_->SetErrorState(
    157           ErrorScreen::ERROR_STATE_PROXY, network_name);
    158       break;
    159     }
    160     case NetworkStateInformer::OFFLINE: {
    161       error_screen_actor_->SetErrorState(
    162           ErrorScreen::ERROR_STATE_OFFLINE, network_name);
    163       break;
    164     }
    165     default:
    166       error_screen_actor_->SetErrorState(
    167           ErrorScreen::ERROR_STATE_OFFLINE, network_name);
    168       NOTREACHED();
    169       break;
    170   };
    171 
    172   OobeUI::Screen screen = OobeUI::SCREEN_UNKNOWN;
    173   OobeUI* oobe_ui = static_cast<OobeUI*>(web_ui()->GetController());
    174   if (oobe_ui)
    175     screen = oobe_ui->current_screen();
    176 
    177   if (screen != OobeUI::SCREEN_ERROR_MESSAGE)
    178     error_screen_actor_->Show(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH, NULL);
    179 }
    180 
    181 void AppLaunchSplashScreenHandler::OnNetworkReady() {
    182   // Purposely leave blank because the online case is handled in UpdateState
    183   // call below.
    184 }
    185 
    186 void AppLaunchSplashScreenHandler::UpdateState(
    187     ErrorScreenActor::ErrorReason reason) {
    188   if (!delegate_ ||
    189       (state_ != APP_LAUNCH_STATE_PREPARING_NETWORK &&
    190        state_ != APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT)) {
    191     return;
    192   }
    193 
    194   NetworkStateInformer::State state = network_state_informer_->state();
    195   delegate_->OnNetworkStateChanged(state == NetworkStateInformer::ONLINE);
    196 }
    197 
    198 void AppLaunchSplashScreenHandler::PopulateAppInfo(
    199     base::DictionaryValue* out_info) {
    200   KioskAppManager::App app;
    201   KioskAppManager::Get()->GetApp(app_id_, &app);
    202 
    203   if (app.name.empty())
    204     app.name = l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME);
    205 
    206   if (app.icon.isNull()) {
    207     app.icon = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    208         IDR_PRODUCT_LOGO_128);
    209   }
    210 
    211   out_info->SetString("name", app.name);
    212   out_info->SetString("iconURL", webui::GetBitmapDataUrl(*app.icon.bitmap()));
    213 }
    214 
    215 void AppLaunchSplashScreenHandler::SetLaunchText(const std::string& text) {
    216   CallJS("updateMessage", text);
    217 }
    218 
    219 int AppLaunchSplashScreenHandler::GetProgressMessageFromState(
    220     AppLaunchState state) {
    221   switch (state) {
    222     case APP_LAUNCH_STATE_LOADING_AUTH_FILE:
    223     case APP_LAUNCH_STATE_LOADING_TOKEN_SERVICE:
    224       // TODO(zelidrag): Add better string for this one than "Please wait..."
    225       return IDS_SYNC_SETUP_SPINNER_TITLE;
    226     case APP_LAUNCH_STATE_PREPARING_NETWORK:
    227       return IDS_APP_START_NETWORK_WAIT_MESSAGE;
    228     case APP_LAUNCH_STATE_INSTALLING_APPLICATION:
    229       return IDS_APP_START_APP_WAIT_MESSAGE;
    230     case APP_LAUNCH_STATE_WAITING_APP_WINDOW:
    231       return IDS_APP_START_WAIT_FOR_APP_WINDOW_MESSAGE;
    232     case APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT:
    233       return IDS_APP_START_NETWORK_WAIT_TIMEOUT_MESSAGE;
    234   }
    235   return IDS_APP_START_NETWORK_WAIT_MESSAGE;
    236 }
    237 
    238 void AppLaunchSplashScreenHandler::HandleConfigureNetwork() {
    239   if (delegate_)
    240     delegate_->OnConfigureNetwork();
    241   else
    242     LOG(WARNING) << "No delegate set to handle network configuration.";
    243 }
    244 
    245 void AppLaunchSplashScreenHandler::HandleCancelAppLaunch() {
    246   if (delegate_)
    247     delegate_->OnCancelAppLaunch();
    248   else
    249     LOG(WARNING) << "No delegate set to handle cancel app launch";
    250 }
    251 
    252 }  // namespace chromeos
    253