// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/login/screens/network_error.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_screen.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "components/login/localized_values_builder.h" #include "grit/chrome_unscaled_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/webui/web_ui_util.h" namespace { const char kJsScreenPath[] = "login.AppLaunchSplashScreen"; // Returns network name by service path. std::string GetNetworkName(const std::string& service_path) { const chromeos::NetworkState* network = chromeos::NetworkHandler::Get()->network_state_handler()->GetNetworkState( service_path); if (!network) return std::string(); return network->name(); } } // namespace namespace chromeos { AppLaunchSplashScreenHandler::AppLaunchSplashScreenHandler( const scoped_refptr<NetworkStateInformer>& network_state_informer, NetworkErrorModel* network_error_model) : BaseScreenHandler(kJsScreenPath), delegate_(NULL), show_on_init_(false), state_(APP_LAUNCH_STATE_LOADING_AUTH_FILE), network_state_informer_(network_state_informer), network_error_model_(network_error_model), online_state_(false), network_config_done_(false), network_config_requested_(false) { network_state_informer_->AddObserver(this); } AppLaunchSplashScreenHandler::~AppLaunchSplashScreenHandler() { network_state_informer_->RemoveObserver(this); } void AppLaunchSplashScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { builder->Add("appStartMessage", IDS_APP_START_NETWORK_WAIT_MESSAGE); builder->Add("configureNetwork", IDS_APP_START_CONFIGURE_NETWORK); const base::string16 product_os_name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME); builder->Add( "shortcutInfo", l10n_util::GetStringFUTF16(IDS_APP_START_BAILOUT_SHORTCUT_FORMAT, product_os_name)); builder->Add( "productName", l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME)); } void AppLaunchSplashScreenHandler::Initialize() { if (show_on_init_) { show_on_init_ = false; Show(app_id_); } } void AppLaunchSplashScreenHandler::Show(const std::string& app_id) { app_id_ = app_id; if (!page_is_ready()) { show_on_init_ = true; return; } base::DictionaryValue data; data.SetBoolean("shortcutEnabled", !KioskAppManager::Get()->GetDisableBailoutShortcut()); // |data| will take ownership of |app_info|. base::DictionaryValue *app_info = new base::DictionaryValue(); PopulateAppInfo(app_info); data.Set("appInfo", app_info); SetLaunchText(l10n_util::GetStringUTF8(GetProgressMessageFromState(state_))); ShowScreenWithData(OobeScreen::SCREEN_APP_LAUNCH_SPLASH, &data); } void AppLaunchSplashScreenHandler::RegisterMessages() { AddCallback("configureNetwork", &AppLaunchSplashScreenHandler::HandleConfigureNetwork); AddCallback("cancelAppLaunch", &AppLaunchSplashScreenHandler::HandleCancelAppLaunch); AddCallback("continueAppLaunch", &AppLaunchSplashScreenHandler::HandleContinueAppLaunch); AddCallback("networkConfigRequest", &AppLaunchSplashScreenHandler::HandleNetworkConfigRequested); } void AppLaunchSplashScreenHandler::PrepareToShow() { } void AppLaunchSplashScreenHandler::Hide() { } void AppLaunchSplashScreenHandler::ToggleNetworkConfig(bool visible) { CallJS("toggleNetworkConfig", visible); } void AppLaunchSplashScreenHandler::UpdateAppLaunchState(AppLaunchState state) { if (state == state_) return; state_ = state; if (page_is_ready()) { SetLaunchText( l10n_util::GetStringUTF8(GetProgressMessageFromState(state_))); } UpdateState(NetworkError::ERROR_REASON_UPDATE); } void AppLaunchSplashScreenHandler::SetDelegate( AppLaunchSplashScreenHandler::Delegate* delegate) { delegate_ = delegate; } void AppLaunchSplashScreenHandler::ShowNetworkConfigureUI() { NetworkStateInformer::State state = network_state_informer_->state(); if (state == NetworkStateInformer::ONLINE) { online_state_ = true; if (!network_config_requested_) { delegate_->OnNetworkStateChanged(true); return; } } const std::string network_path = network_state_informer_->network_path(); const std::string network_name = GetNetworkName(network_path); network_error_model_->SetUIState(NetworkError::UI_STATE_KIOSK_MODE); network_error_model_->AllowGuestSignin(false); network_error_model_->AllowOfflineLogin(false); switch (state) { case NetworkStateInformer::CAPTIVE_PORTAL: { network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PORTAL, network_name); network_error_model_->FixCaptivePortal(); break; } case NetworkStateInformer::PROXY_AUTH_REQUIRED: { network_error_model_->SetErrorState(NetworkError::ERROR_STATE_PROXY, network_name); break; } case NetworkStateInformer::OFFLINE: { network_error_model_->SetErrorState(NetworkError::ERROR_STATE_OFFLINE, network_name); break; } case NetworkStateInformer::ONLINE: { network_error_model_->SetErrorState( NetworkError::ERROR_STATE_KIOSK_ONLINE, network_name); break; } default: network_error_model_->SetErrorState(NetworkError::ERROR_STATE_OFFLINE, network_name); NOTREACHED(); break; } OobeScreen screen = OobeScreen::SCREEN_UNKNOWN; OobeUI* oobe_ui = static_cast<OobeUI*>(web_ui()->GetController()); if (oobe_ui) screen = oobe_ui->current_screen(); if (screen != OobeScreen::SCREEN_ERROR_MESSAGE) network_error_model_->SetParentScreen(OobeScreen::SCREEN_APP_LAUNCH_SPLASH); network_error_model_->Show(); } bool AppLaunchSplashScreenHandler::IsNetworkReady() { return network_state_informer_->state() == NetworkStateInformer::ONLINE; } void AppLaunchSplashScreenHandler::OnNetworkReady() { // Purposely leave blank because the online case is handled in UpdateState // call below. } void AppLaunchSplashScreenHandler::UpdateState( NetworkError::ErrorReason reason) { if (!delegate_ || (state_ != APP_LAUNCH_STATE_PREPARING_NETWORK && state_ != APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT)) { return; } bool new_online_state = network_state_informer_->state() == NetworkStateInformer::ONLINE; delegate_->OnNetworkStateChanged(new_online_state); online_state_ = new_online_state; } void AppLaunchSplashScreenHandler::PopulateAppInfo( base::DictionaryValue* out_info) { KioskAppManager::App app; KioskAppManager::Get()->GetApp(app_id_, &app); if (app.name.empty()) app.name = l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME); if (app.icon.isNull()) { app.icon = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PRODUCT_LOGO_128); } out_info->SetString("name", app.name); out_info->SetString("iconURL", webui::GetBitmapDataUrl(*app.icon.bitmap())); } void AppLaunchSplashScreenHandler::SetLaunchText(const std::string& text) { CallJS("updateMessage", text); } int AppLaunchSplashScreenHandler::GetProgressMessageFromState( AppLaunchState state) { switch (state) { case APP_LAUNCH_STATE_LOADING_AUTH_FILE: case APP_LAUNCH_STATE_LOADING_TOKEN_SERVICE: // TODO(zelidrag): Add better string for this one than "Please wait..." return IDS_SYNC_SETUP_SPINNER_TITLE; case APP_LAUNCH_STATE_PREPARING_NETWORK: return IDS_APP_START_NETWORK_WAIT_MESSAGE; case APP_LAUNCH_STATE_INSTALLING_APPLICATION: return IDS_APP_START_APP_WAIT_MESSAGE; case APP_LAUNCH_STATE_WAITING_APP_WINDOW: return IDS_APP_START_WAIT_FOR_APP_WINDOW_MESSAGE; case APP_LAUNCH_STATE_NETWORK_WAIT_TIMEOUT: return IDS_APP_START_NETWORK_WAIT_TIMEOUT_MESSAGE; } return IDS_APP_START_NETWORK_WAIT_MESSAGE; } void AppLaunchSplashScreenHandler::HandleConfigureNetwork() { if (delegate_) delegate_->OnConfigureNetwork(); else LOG(WARNING) << "No delegate set to handle network configuration."; } void AppLaunchSplashScreenHandler::HandleCancelAppLaunch() { if (delegate_) delegate_->OnCancelAppLaunch(); else LOG(WARNING) << "No delegate set to handle cancel app launch"; } void AppLaunchSplashScreenHandler::HandleNetworkConfigRequested() { if (!delegate_ || network_config_done_) return; network_config_requested_ = true; delegate_->OnNetworkConfigRequested(true); } void AppLaunchSplashScreenHandler::HandleContinueAppLaunch() { DCHECK(online_state_); if (delegate_ && online_state_) { network_config_requested_ = false; network_config_done_ = true; delegate_->OnNetworkConfigRequested(false); Show(app_id_); } } } // namespace chromeos