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 19namespace { 20 21const char kJsScreenPath[] = "login.AppLaunchSplashScreen"; 22 23// Returns network name by service path. 24std::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 35namespace chromeos { 36 37AppLaunchSplashScreenHandler::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 52AppLaunchSplashScreenHandler::~AppLaunchSplashScreenHandler() { 53 network_state_informer_->RemoveObserver(this); 54} 55 56void 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 74void AppLaunchSplashScreenHandler::Initialize() { 75 if (show_on_init_) { 76 show_on_init_ = false; 77 Show(app_id_); 78 } 79} 80 81void 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 101void 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 112void AppLaunchSplashScreenHandler::PrepareToShow() { 113} 114 115void AppLaunchSplashScreenHandler::Hide() { 116} 117 118void AppLaunchSplashScreenHandler::ToggleNetworkConfig(bool visible) { 119 CallJS("toggleNetworkConfig", visible); 120} 121 122void 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 134void AppLaunchSplashScreenHandler::SetDelegate( 135 AppLaunchSplashScreenHandler::Delegate* delegate) { 136 delegate_ = delegate; 137} 138 139void 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 195bool AppLaunchSplashScreenHandler::IsNetworkReady() { 196 return network_state_informer_->state() == NetworkStateInformer::ONLINE; 197} 198 199void AppLaunchSplashScreenHandler::OnNetworkReady() { 200 // Purposely leave blank because the online case is handled in UpdateState 201 // call below. 202} 203 204void 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 219void 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 236void AppLaunchSplashScreenHandler::SetLaunchText(const std::string& text) { 237 CallJS("updateMessage", text); 238} 239 240int 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 259void AppLaunchSplashScreenHandler::HandleConfigureNetwork() { 260 if (delegate_) 261 delegate_->OnConfigureNetwork(); 262 else 263 LOG(WARNING) << "No delegate set to handle network configuration."; 264} 265 266void AppLaunchSplashScreenHandler::HandleCancelAppLaunch() { 267 if (delegate_) 268 delegate_->OnCancelAppLaunch(); 269 else 270 LOG(WARNING) << "No delegate set to handle cancel app launch"; 271} 272 273void AppLaunchSplashScreenHandler::HandleNetworkConfigRequested() { 274 if (!delegate_ || network_config_done_) 275 return; 276 277 network_config_requested_ = true; 278 delegate_->OnNetworkConfigRequested(true); 279} 280 281void 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