1// Copyright (c) 2011 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/chromeos/login/registration_screen.h"
6
7#include "base/logging.h"
8#include "base/string_util.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chromeos/input_method/input_method_util.h"
11#include "chrome/browser/profiles/profile_manager.h"
12#include "chrome/common/url_constants.h"
13#include "content/browser/child_process_security_policy.h"
14#include "content/browser/renderer_host/render_view_host.h"
15#include "content/browser/site_instance.h"
16#include "content/browser/tab_contents/tab_contents.h"
17#include "googleurl/src/gurl.h"
18#include "net/url_request/url_request_about_job.h"
19#include "net/url_request/url_request_filter.h"
20#include "views/widget/widget_gtk.h"
21
22namespace chromeos {
23
24namespace {
25
26const char kRegistrationHostPageUrl[] = "chrome://register/";
27
28// "Hostname" that is used for redirects from host registration page.
29const char kRegistrationHostnameUrl[] = "register";
30
31// Host page navigates to these URLs in case of success/skipped registration.
32const char kRegistrationSuccessUrl[] = "cros://register/success";
33const char kRegistrationSkippedUrl[] = "cros://register/skipped";
34
35}  // namespace
36
37///////////////////////////////////////////////////////////////////////////////
38// RegistrationScreen, public:
39RegistrationScreen::RegistrationScreen(WizardScreenDelegate* delegate)
40    : ViewScreen<RegistrationView>(delegate) {
41  if (!host_page_url_.get())
42    set_registration_host_page_url(GURL(kRegistrationHostPageUrl));
43
44  ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
45      chrome::kCrosScheme);
46  net::URLRequestFilter::GetInstance()->AddHostnameHandler(
47      chrome::kCrosScheme,
48      kRegistrationHostnameUrl,
49      &RegistrationScreen::Factory);
50}
51
52// static
53void RegistrationScreen::set_registration_host_page_url(const GURL& url) {
54  host_page_url_.reset(new GURL(url));
55}
56
57// static
58scoped_ptr<GURL> RegistrationScreen::host_page_url_;
59
60///////////////////////////////////////////////////////////////////////////////
61// RegistrationScreen, ViewScreen implementation:
62void RegistrationScreen::CreateView() {
63  ViewScreen<RegistrationView>::CreateView();
64  view()->SetWebPageDelegate(this);
65}
66
67void RegistrationScreen::Refresh() {
68  StartTimeoutTimer();
69  GURL url(*host_page_url_);
70  Profile* profile = ProfileManager::GetDefaultProfile();
71  view()->InitDOM(profile,
72                  SiteInstance::CreateSiteInstanceForURL(profile, url));
73  view()->SetTabContentsDelegate(this);
74  view()->LoadURL(url);
75}
76
77RegistrationView* RegistrationScreen::AllocateView() {
78  return new RegistrationView();
79}
80
81///////////////////////////////////////////////////////////////////////////////
82// RegistrationScreen, WebPageDelegate implementation:
83void RegistrationScreen::OnPageLoaded() {
84  StopTimeoutTimer();
85  // Enable input methods (e.g. Chinese, Japanese) so that users could input
86  // their first and last names.
87  if (g_browser_process) {
88    const std::string locale = g_browser_process->GetApplicationLocale();
89    input_method::EnableInputMethods(
90        locale, input_method::kAllInputMethods, "");
91  }
92  view()->ShowPageContent();
93}
94
95void RegistrationScreen::OnPageLoadFailed(const std::string& url) {
96  LOG(ERROR) << "Error loading registration page: " << url;
97  CloseScreen(ScreenObserver::REGISTRATION_SKIPPED);
98}
99
100///////////////////////////////////////////////////////////////////////////////
101// RegistrationScreen, TabContentsDelegate implementation:
102 void RegistrationScreen::OpenURLFromTab(TabContents* source,
103                                         const GURL& url,
104                                         const GURL& referrer,
105                                         WindowOpenDisposition disposition,
106                                         PageTransition::Type transition) {
107  if (url.spec() == kRegistrationSuccessUrl) {
108    source->Stop();
109    VLOG(1) << "Registration form completed.";
110    CloseScreen(ScreenObserver::REGISTRATION_SUCCESS);
111  } else if (url.spec() == kRegistrationSkippedUrl) {
112    source->Stop();
113    VLOG(1) << "Registration form skipped.";
114    CloseScreen(ScreenObserver::REGISTRATION_SKIPPED);
115  } else {
116    source->Stop();
117    // Host registration page and actual registration page hosted by
118    // OEM partner doesn't contain links to external URLs.
119    LOG(WARNING) << "Navigate to unsupported url: " << url.spec();
120  }
121}
122
123void RegistrationScreen::HandleKeyboardEvent(
124    const NativeWebKeyboardEvent& event) {
125  views::Widget* widget = view()->GetWidget();
126  if (widget && event.os_event && !event.skip_in_browser) {
127    views::KeyEvent views_event(reinterpret_cast<GdkEvent*>(event.os_event));
128    static_cast<views::WidgetGtk*>(widget)->HandleKeyboardEvent(views_event);
129  }
130}
131
132///////////////////////////////////////////////////////////////////////////////
133// RegistrationScreen, private:
134void RegistrationScreen::CloseScreen(ScreenObserver::ExitCodes code) {
135  StopTimeoutTimer();
136  // Disable input methods since they are not necessary to input username and
137  // password.
138  if (g_browser_process) {
139    const std::string locale = g_browser_process->GetApplicationLocale();
140    input_method::EnableInputMethods(
141        locale, input_method::kKeyboardLayoutsOnly, "");
142  }
143  delegate()->GetObserver(this)->OnExit(code);
144}
145
146// static
147net::URLRequestJob* RegistrationScreen::Factory(net::URLRequest* request,
148                                                const std::string& scheme) {
149  VLOG(1) << "Handling url: " << request->url().spec().c_str();
150  return new net::URLRequestAboutJob(request);
151}
152
153}  // namespace chromeos
154