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.
GetNetworkName(const std::string & 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
AppLaunchSplashScreenHandler(const scoped_refptr<NetworkStateInformer> & network_state_informer,ErrorScreenActor * error_screen_actor)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
~AppLaunchSplashScreenHandler()50 AppLaunchSplashScreenHandler::~AppLaunchSplashScreenHandler() {
51 network_state_informer_->RemoveObserver(this);
52 }
53
DeclareLocalizedValues(LocalizedValuesBuilder * builder)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
Initialize()72 void AppLaunchSplashScreenHandler::Initialize() {
73 if (show_on_init_) {
74 show_on_init_ = false;
75 Show(app_id_);
76 }
77 }
78
Show(const std::string & app_id)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
RegisterMessages()99 void AppLaunchSplashScreenHandler::RegisterMessages() {
100 AddCallback("configureNetwork",
101 &AppLaunchSplashScreenHandler::HandleConfigureNetwork);
102 AddCallback("cancelAppLaunch",
103 &AppLaunchSplashScreenHandler::HandleCancelAppLaunch);
104 }
105
PrepareToShow()106 void AppLaunchSplashScreenHandler::PrepareToShow() {
107 }
108
Hide()109 void AppLaunchSplashScreenHandler::Hide() {
110 }
111
ToggleNetworkConfig(bool visible)112 void AppLaunchSplashScreenHandler::ToggleNetworkConfig(bool visible) {
113 CallJS("toggleNetworkConfig", visible);
114 }
115
UpdateAppLaunchState(AppLaunchState state)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
SetDelegate(AppLaunchSplashScreenHandler::Delegate * delegate)128 void AppLaunchSplashScreenHandler::SetDelegate(
129 AppLaunchSplashScreenHandler::Delegate* delegate) {
130 delegate_ = delegate;
131 }
132
ShowNetworkConfigureUI()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
OnNetworkReady()181 void AppLaunchSplashScreenHandler::OnNetworkReady() {
182 // Purposely leave blank because the online case is handled in UpdateState
183 // call below.
184 }
185
UpdateState(ErrorScreenActor::ErrorReason reason)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
PopulateAppInfo(base::DictionaryValue * out_info)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
SetLaunchText(const std::string & text)215 void AppLaunchSplashScreenHandler::SetLaunchText(const std::string& text) {
216 CallJS("updateMessage", text);
217 }
218
GetProgressMessageFromState(AppLaunchState state)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
HandleConfigureNetwork()238 void AppLaunchSplashScreenHandler::HandleConfigureNetwork() {
239 if (delegate_)
240 delegate_->OnConfigureNetwork();
241 else
242 LOG(WARNING) << "No delegate set to handle network configuration.";
243 }
244
HandleCancelAppLaunch()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