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