Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / login / screens / error_screen.cc
blobdd4cdb50cb881d90f1fb55c69fcd1bb32bdb3ab0
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/chromeos/login/screens/error_screen.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "chrome/browser/app_mode/app_mode_utils.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
14 #include "chrome/browser/chromeos/app_mode/certificate_manager_dialog.h"
15 #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
16 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
17 #include "chrome/browser/chromeos/login/screens/network_error_view.h"
18 #include "chrome/browser/chromeos/login/startup_utils.h"
19 #include "chrome/browser/chromeos/login/ui/captive_portal_window_proxy.h"
20 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
21 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
22 #include "chrome/browser/chromeos/login/wizard_controller.h"
23 #include "chrome/browser/chromeos/profiles/profile_helper.h"
24 #include "chrome/browser/chromeos/settings/cros_settings.h"
25 #include "chrome/browser/chromeos/settings/device_settings_service.h"
26 #include "chrome/browser/extensions/component_loader.h"
27 #include "chrome/browser/extensions/extension_service.h"
28 #include "chrome/browser/profiles/profile_manager.h"
29 #include "chrome/browser/ui/extensions/app_launch_params.h"
30 #include "chrome/browser/ui/extensions/application_launch.h"
31 #include "chrome/common/extensions/extension_constants.h"
32 #include "chromeos/dbus/dbus_thread_manager.h"
33 #include "chromeos/dbus/power_manager_client.h"
34 #include "chromeos/dbus/session_manager_client.h"
35 #include "chromeos/network/portal_detector/network_portal_detector.h"
36 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
37 #include "components/user_manager/user_manager.h"
38 #include "content/public/browser/notification_service.h"
39 #include "extensions/browser/extension_system.h"
40 #include "extensions/common/constants.h"
41 #include "grit/browser_resources.h"
42 #include "ui/gfx/native_widget_types.h"
44 namespace chromeos {
46 namespace {
48 // Returns the current running kiosk app profile in a kiosk session. Otherwise,
49 // returns nullptr.
50 Profile* GetAppProfile() {
51 return chrome::IsRunningInForcedAppMode()
52 ? ProfileManager::GetActiveUserProfile()
53 : nullptr;
56 } // namespace
58 ErrorScreen::ErrorScreen(BaseScreenDelegate* base_screen_delegate,
59 NetworkErrorView* view)
60 : NetworkErrorModel(base_screen_delegate),
61 view_(view),
62 ui_state_(NetworkError::UI_STATE_UNKNOWN),
63 error_state_(NetworkError::ERROR_STATE_UNKNOWN),
64 parent_screen_(OobeUI::SCREEN_UNKNOWN),
65 weak_factory_(this) {
66 network_state_informer_ = new NetworkStateInformer();
67 network_state_informer_->Init();
68 if (view_)
69 view_->Bind(*this);
72 ErrorScreen::~ErrorScreen() {
73 if (view_)
74 view_->Unbind();
77 void ErrorScreen::PrepareToShow() {
78 if (view_)
79 view_->PrepareToShow();
82 void ErrorScreen::Show() {
83 if (!on_hide_callback_) {
84 SetHideCallback(base::Bind(&ErrorScreen::DefaultHideCallback,
85 weak_factory_.GetWeakPtr()));
87 if (view_)
88 view_->Show();
91 void ErrorScreen::Hide() {
92 if (view_)
93 view_->Hide();
96 void ErrorScreen::OnShow() {
97 LOG(WARNING) << "Network error screen message is shown";
98 content::NotificationService::current()->Notify(
99 chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN,
100 content::NotificationService::AllSources(),
101 content::NotificationService::NoDetails());
102 NetworkPortalDetector::Get()->SetStrategy(
103 PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN);
106 void ErrorScreen::OnHide() {
107 LOG(WARNING) << "Network error screen message is hidden";
108 if (on_hide_callback_) {
109 on_hide_callback_->Run();
110 on_hide_callback_.reset();
112 NetworkPortalDetector::Get()->SetStrategy(
113 PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN);
116 void ErrorScreen::OnUserAction(const std::string& action_id) {
117 if (action_id == kUserActionShowCaptivePortalClicked)
118 ShowCaptivePortal();
119 else if (action_id == kUserActionConfigureCertsButtonClicked)
120 OnConfigureCerts();
121 else if (action_id == kUserActionDiagnoseButtonClicked)
122 OnDiagnoseButtonClicked();
123 else if (action_id == kUserActionLaunchOobeGuestSessionClicked)
124 OnLaunchOobeGuestSession();
125 else if (action_id == kUserActionLocalStateErrorPowerwashButtonClicked)
126 OnLocalStateErrorPowerwashButtonClicked();
127 else if (action_id == kUserActionRebootButtonClicked)
128 OnRebootButtonClicked();
129 else if (action_id == kUserActionConnectRequested)
130 OnConnectRequested();
131 else
132 BaseScreen::OnUserAction(action_id);
135 void ErrorScreen::OnContextKeyUpdated(
136 const ::login::ScreenContext::KeyType& key) {
137 BaseScreen::OnContextKeyUpdated(key);
140 void ErrorScreen::AllowGuestSignin(bool allowed) {
141 GetContextEditor().SetBoolean(kContextKeyGuestSigninAllowed, allowed);
144 void ErrorScreen::AllowOfflineLogin(bool allowed) {
145 GetContextEditor().SetBoolean(kContextKeyOfflineSigninAllowed, allowed);
148 void ErrorScreen::FixCaptivePortal() {
149 if (!captive_portal_window_proxy_.get()) {
150 content::WebContents* web_contents = LoginDisplayHostImpl::default_host()
151 ->GetWebUILoginView()
152 ->GetWebContents();
153 captive_portal_window_proxy_.reset(new CaptivePortalWindowProxy(
154 network_state_informer_.get(), web_contents));
156 captive_portal_window_proxy_->ShowIfRedirected();
159 NetworkError::UIState ErrorScreen::GetUIState() const {
160 return ui_state_;
163 NetworkError::ErrorState ErrorScreen::GetErrorState() const {
164 return error_state_;
167 OobeUI::Screen ErrorScreen::GetParentScreen() const {
168 return parent_screen_;
171 void ErrorScreen::HideCaptivePortal() {
172 if (captive_portal_window_proxy_.get())
173 captive_portal_window_proxy_->Close();
176 void ErrorScreen::OnViewDestroyed(NetworkErrorView* view) {
177 if (view_ == view)
178 view_ = nullptr;
181 void ErrorScreen::SetUIState(NetworkError::UIState ui_state) {
182 ui_state_ = ui_state;
183 GetContextEditor().SetInteger(kContextKeyUIState,
184 static_cast<int>(ui_state_));
187 void ErrorScreen::SetErrorState(NetworkError::ErrorState error_state,
188 const std::string& network) {
189 error_state_ = error_state;
190 GetContextEditor()
191 .SetInteger(kContextKeyErrorStateCode, static_cast<int>(error_state_))
192 .SetString(kContextKeyErrorStateNetwork, network);
195 void ErrorScreen::SetParentScreen(OobeUI::Screen parent_screen) {
196 parent_screen_ = parent_screen;
197 // Not really used on JS side yet so no need to propagate to screen context.
200 void ErrorScreen::SetHideCallback(const base::Closure& on_hide) {
201 on_hide_callback_.reset(new base::Closure(on_hide));
204 void ErrorScreen::ShowCaptivePortal() {
205 // This call is an explicit user action
206 // i.e. clicking on link so force dialog show.
207 FixCaptivePortal();
208 captive_portal_window_proxy_->Show();
211 void ErrorScreen::ShowConnectingIndicator(bool show) {
212 GetContextEditor().SetBoolean(kContextKeyShowConnectingIndicator, show);
215 void ErrorScreen::OnAuthFailure(const AuthFailure& error) {
216 // The only condition leading here is guest mount failure, which should not
217 // happen in practice. For now, just log an error so this situation is visible
218 // in logs if it ever occurs.
219 NOTREACHED() << "Guest login failed.";
220 guest_login_performer_.reset();
223 void ErrorScreen::OnAuthSuccess(const UserContext& user_context) {
224 LOG(FATAL);
227 void ErrorScreen::OnOffTheRecordAuthSuccess() {
228 // Restart Chrome to enter the guest session.
229 const base::CommandLine& browser_command_line =
230 *base::CommandLine::ForCurrentProcess();
231 base::CommandLine command_line(browser_command_line.GetProgram());
232 GetOffTheRecordCommandLine(GURL(), StartupUtils::IsOobeCompleted(),
233 browser_command_line, &command_line);
234 RestartChrome(command_line);
237 void ErrorScreen::OnPasswordChangeDetected() {
238 LOG(FATAL);
241 void ErrorScreen::WhiteListCheckFailed(const std::string& email) {
242 LOG(FATAL);
245 void ErrorScreen::PolicyLoadFailed() {
246 LOG(FATAL);
249 ErrorScreen::ConnectRequestCallbackSubscription
250 ErrorScreen::RegisterConnectRequestCallback(const base::Closure& callback) {
251 return connect_request_callbacks_.Add(callback);
254 void ErrorScreen::DefaultHideCallback() {
255 if (parent_screen_ != OobeUI::SCREEN_UNKNOWN && view_)
256 view_->ShowScreen(parent_screen_);
258 // TODO(antrim): Due to potential race with GAIA reload and hiding network
259 // error UI we can't just reset parent screen to SCREEN_UNKNOWN here.
262 void ErrorScreen::OnConfigureCerts() {
263 gfx::NativeWindow native_window =
264 LoginDisplayHostImpl::default_host()->GetNativeWindow();
265 CertificateManagerDialog* dialog = new CertificateManagerDialog(
266 GetAppProfile(), NULL, native_window);
267 dialog->Show();
270 void ErrorScreen::OnDiagnoseButtonClicked() {
271 Profile* profile = GetAppProfile();
272 ExtensionService* extension_service =
273 extensions::ExtensionSystem::Get(profile)->extension_service();
275 std::string extension_id = extension_service->component_loader()->Add(
276 IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
277 base::FilePath(extension_misc::kConnectivityDiagnosticsPath));
279 const extensions::Extension* extension =
280 extension_service->GetExtensionById(extension_id, true);
281 OpenApplication(
282 AppLaunchParams(profile, extension, extensions::LAUNCH_CONTAINER_WINDOW,
283 NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL));
284 InitAppSession(profile, extension_id);
286 user_manager::UserManager::Get()->SessionStarted();
288 LoginDisplayHostImpl::default_host()->Finalize();
291 void ErrorScreen::OnLaunchOobeGuestSession() {
292 DeviceSettingsService::Get()->GetOwnershipStatusAsync(
293 base::Bind(&ErrorScreen::StartGuestSessionAfterOwnershipCheck,
294 weak_factory_.GetWeakPtr()));
297 void ErrorScreen::OnLocalStateErrorPowerwashButtonClicked() {
298 chromeos::DBusThreadManager::Get()
299 ->GetSessionManagerClient()
300 ->StartDeviceWipe();
303 void ErrorScreen::OnRebootButtonClicked() {
304 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
307 void ErrorScreen::OnConnectRequested() {
308 connect_request_callbacks_.Notify();
311 void ErrorScreen::StartGuestSessionAfterOwnershipCheck(
312 DeviceSettingsService::OwnershipStatus ownership_status) {
314 // Make sure to disallow guest login if it's explicitly disabled.
315 CrosSettingsProvider::TrustedStatus trust_status =
316 CrosSettings::Get()->PrepareTrustedValues(
317 base::Bind(&ErrorScreen::StartGuestSessionAfterOwnershipCheck,
318 weak_factory_.GetWeakPtr(),
319 ownership_status));
320 switch (trust_status) {
321 case CrosSettingsProvider::TEMPORARILY_UNTRUSTED:
322 // Wait for a callback.
323 return;
324 case CrosSettingsProvider::PERMANENTLY_UNTRUSTED:
325 // Only allow guest sessions if there is no owner yet.
326 if (ownership_status == DeviceSettingsService::OWNERSHIP_NONE)
327 break;
328 return;
329 case CrosSettingsProvider::TRUSTED: {
330 // Honor kAccountsPrefAllowGuest.
331 bool allow_guest = false;
332 CrosSettings::Get()->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
333 if (allow_guest)
334 break;
335 return;
339 if (guest_login_performer_)
340 return;
342 guest_login_performer_.reset(new ChromeLoginPerformer(this));
343 guest_login_performer_->LoginOffTheRecord();
346 } // namespace chromeos