• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ui/webui/chromeos/register_page_ui.h"
6 
7 #include <string>
8 
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/string_piece.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chromeos/cros/cros_library.h"
17 #include "chrome/browser/chromeos/cros/network_library.h"
18 #include "chrome/browser/chromeos/customization_document.h"
19 #include "chrome/browser/chromeos/login/wizard_controller.h"
20 #include "chrome/browser/chromeos/system_access.h"
21 #include "chrome/browser/chromeos/version_loader.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
24 #include "chrome/common/url_constants.h"
25 #include "content/browser/browser_thread.h"
26 #include "content/browser/tab_contents/tab_contents.h"
27 #include "googleurl/src/gurl.h"
28 #include "grit/browser_resources.h"
29 #include "ui/base/resource/resource_bundle.h"
30 
31 namespace {
32 
33 // Host page JS API callback names.
34 const char kJsCallbackGetRegistrationUrl[] = "getRegistrationUrl";
35 const char kJsCallbackUserInfo[] = "getUserInfo";
36 
37 // Host page JS API function names.
38 const char kJsApiSetRegistrationUrl[] = "setRegistrationUrl";
39 const char kJsApiSetUserInfo[] = "setUserInfo";
40 const char kJsApiSkipRegistration[] = "skipRegistration";
41 
42 // Constant value for os_name sent in setUserInfo.
43 const char kOSName[] = "ChromeOS";
44 
45 // MachineInfo keys names.
46 const char kMachineInfoSystemHwqual[] = "hardware_class";
47 const char kMachineInfoSerialNumber[] = "serial_number";
48 
49 // Types of network connection.
50 const char kConnectionEthernet[] = "ethernet";
51 const char kConnectionWifi[] = "wifi";
52 const char kConnection3g[] = "3g";
53 const char kUndefinedValue[] = "undefined";
54 
55 // Utility function that returns string corresponding to currently active
56 // connection type |kConnectionEthernet|kConnectionWifi|kConnection3g|.
57 // If multiple interfaces are connected, result is based on the
58 // priority Ethernet-Wifi-Cellular.
59 // If there's no interface that's connected, interface that's in connecting
60 // state is considered as the active one.
61 // Otherwise |kUndefinedValue| is returned.
62 #if defined(OS_CHROMEOS)
GetConnectionType()63 static std::string GetConnectionType() {
64   if (!chromeos::CrosLibrary::Get()->EnsureLoaded()) {
65     LOG(ERROR) << "CrosLibrary is not loaded.";
66     return kUndefinedValue;
67   }
68 
69   chromeos::NetworkLibrary* network_lib =
70       chromeos::CrosLibrary::Get()->GetNetworkLibrary();
71   if (network_lib->ethernet_connected())
72     return kConnectionEthernet;
73   else if (network_lib->wifi_connected())
74     return kConnectionWifi;
75   else if (network_lib->cellular_connected())
76     return kConnection3g;
77   // Connection might have been lost and is in reconnecting state at this point.
78   else if (network_lib->ethernet_connecting())
79     return kConnectionEthernet;
80   else if (network_lib->wifi_connecting())
81     return kConnectionWifi;
82   else if (network_lib->cellular_connecting())
83     return kConnection3g;
84   else
85     return kUndefinedValue;
86 }
87 #endif
88 
89 }  // namespace
90 
91 class RegisterPageUIHTMLSource : public ChromeURLDataManager::DataSource {
92  public:
93   RegisterPageUIHTMLSource();
94 
95   // Called when the network layer has requested a resource underneath
96   // the path we registered.
97   virtual void StartDataRequest(const std::string& path,
98                                 bool is_incognito,
99                                 int request_id);
GetMimeType(const std::string &) const100   virtual std::string GetMimeType(const std::string&) const {
101     return "text/html";
102   }
103 
104  private:
~RegisterPageUIHTMLSource()105   ~RegisterPageUIHTMLSource() {}
106 
107   DISALLOW_COPY_AND_ASSIGN(RegisterPageUIHTMLSource);
108 };
109 
110 // The handler for Javascript messages related to the "register" view.
111 class RegisterPageHandler : public WebUIMessageHandler,
112                             public base::SupportsWeakPtr<RegisterPageHandler> {
113  public:
114   RegisterPageHandler();
115   virtual ~RegisterPageHandler();
116 
117   // Init work after Attach.
118   void Init();
119 
120   // WebUIMessageHandler implementation.
121   virtual WebUIMessageHandler* Attach(WebUI* web_ui);
122   virtual void RegisterMessages();
123 
124  private:
125   // Handlers for JS WebUI messages.
126   void HandleGetRegistrationUrl(const ListValue* args);
127   void HandleGetUserInfo(const ListValue* args);
128 
129 #if defined(OS_CHROMEOS)
130   // Callback from chromeos::VersionLoader giving the version.
131   void OnVersion(chromeos::VersionLoader::Handle handle, std::string version);
132 #endif
133 
134   // Skips registration logging |error_msg| with log type ERROR.
135   void SkipRegistration(const std::string& error_msg);
136 
137   // Sends message to host registration page with system/user info data.
138   void SendUserInfo();
139 
140 #if defined(OS_CHROMEOS)
141   // Handles asynchronously loading the version.
142   chromeos::VersionLoader version_loader_;
143 #endif
144 
145   // Used to request the version.
146   CancelableRequestConsumer version_consumer_;
147 
148   std::string version_;
149 
150   DISALLOW_COPY_AND_ASSIGN(RegisterPageHandler);
151 };
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 //
155 // RegisterPageUIHTMLSource
156 //
157 ////////////////////////////////////////////////////////////////////////////////
158 
RegisterPageUIHTMLSource()159 RegisterPageUIHTMLSource::RegisterPageUIHTMLSource()
160     : DataSource(chrome::kChromeUIRegisterPageHost, MessageLoop::current()) {
161 }
162 
StartDataRequest(const std::string & path,bool is_incognito,int request_id)163 void RegisterPageUIHTMLSource::StartDataRequest(const std::string& path,
164                                                 bool is_incognito,
165                                                 int request_id) {
166   // Make sure that chrome://register is available only during
167   // OOBE wizard lifetime and when device has not been registered yet.
168 #if defined(OS_CHROMEOS)
169   if (!WizardController::default_controller() ||
170       WizardController::IsDeviceRegistered()) {
171     scoped_refptr<RefCountedBytes> empty_bytes(new RefCountedBytes);
172     SendResponse(request_id, empty_bytes);
173     return;
174   }
175 
176   static const base::StringPiece register_html(
177       ResourceBundle::GetSharedInstance().GetRawDataResource(
178           IDR_HOST_REGISTRATION_PAGE_HTML));
179 
180   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
181   html_bytes->data.resize(register_html.size());
182   std::copy(register_html.begin(),
183             register_html.end(),
184             html_bytes->data.begin());
185 
186   SendResponse(request_id, html_bytes);
187 #else
188   scoped_refptr<RefCountedBytes> empty_bytes(new RefCountedBytes);
189   SendResponse(request_id, empty_bytes);
190 #endif
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 //
195 // RegisterPageHandler
196 //
197 ////////////////////////////////////////////////////////////////////////////////
RegisterPageHandler()198 RegisterPageHandler::RegisterPageHandler() {
199 }
200 
~RegisterPageHandler()201 RegisterPageHandler::~RegisterPageHandler() {
202 }
203 
Attach(WebUI * web_ui)204 WebUIMessageHandler* RegisterPageHandler::Attach(WebUI* web_ui) {
205   return WebUIMessageHandler::Attach(web_ui);
206 }
207 
Init()208 void RegisterPageHandler::Init() {
209 }
210 
RegisterMessages()211 void RegisterPageHandler::RegisterMessages() {
212 #if defined(OS_CHROMEOS)
213   web_ui_->RegisterMessageCallback(kJsCallbackGetRegistrationUrl,
214       NewCallback(this, &RegisterPageHandler::HandleGetRegistrationUrl));
215   web_ui_->RegisterMessageCallback(kJsCallbackUserInfo,
216       NewCallback(this, &RegisterPageHandler::HandleGetUserInfo));
217 #endif
218 }
219 
HandleGetRegistrationUrl(const ListValue * args)220 void RegisterPageHandler::HandleGetRegistrationUrl(const ListValue* args) {
221 #if defined(OS_CHROMEOS)
222   chromeos::StartupCustomizationDocument* customization =
223     chromeos::StartupCustomizationDocument::GetInstance();
224   if (WizardController::default_controller() &&
225       customization->IsReady()) {
226     const std::string& url = customization->registration_url();
227     VLOG(1) << "Loading registration form with URL: " << url;
228     GURL register_url(url);
229     if (!register_url.is_valid()) {
230       SkipRegistration("Registration URL defined in manifest is invalid.");
231       return;
232     }
233     StringValue url_value(url);
234     web_ui_->CallJavascriptFunction(kJsApiSetRegistrationUrl, url_value);
235   } else {
236     SkipRegistration("Startup manifest not defined.");
237   }
238 #endif
239 }
240 
HandleGetUserInfo(const ListValue * args)241 void RegisterPageHandler::HandleGetUserInfo(const ListValue* args) {
242 #if defined(OS_CHROMEOS)
243   if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
244      version_loader_.GetVersion(
245          &version_consumer_,
246          NewCallback(this,
247                      &RegisterPageHandler::OnVersion),
248          chromeos::VersionLoader::VERSION_FULL);
249   } else {
250     SkipRegistration("CrosLibrary is not loaded.");
251   }
252 #endif
253 }
254 
255 #if defined(OS_CHROMEOS)
OnVersion(chromeos::VersionLoader::Handle handle,std::string version)256 void RegisterPageHandler::OnVersion(chromeos::VersionLoader::Handle handle,
257                                     std::string version) {
258   version_ = version;
259   SendUserInfo();
260 }
261 #endif
262 
SkipRegistration(const std::string & error_msg)263 void RegisterPageHandler::SkipRegistration(const std::string& error_msg) {
264 #if defined(OS_CHROMEOS)
265   LOG(ERROR) << error_msg;
266   if (WizardController::default_controller())
267     WizardController::default_controller()->SkipRegistration();
268   else
269     web_ui_->CallJavascriptFunction(kJsApiSkipRegistration);
270 #endif
271 }
272 
SendUserInfo()273 void RegisterPageHandler::SendUserInfo() {
274 #if defined(OS_CHROMEOS)
275   DictionaryValue value;
276 
277   chromeos::SystemAccess * sys_lib =
278       chromeos::SystemAccess::GetInstance();
279 
280   // Required info.
281   std::string system_hwqual;
282   std::string serial_number;
283   if (!sys_lib->GetMachineStatistic(kMachineInfoSystemHwqual, &system_hwqual) ||
284       !sys_lib->GetMachineStatistic(kMachineInfoSerialNumber, &serial_number)) {
285     SkipRegistration("Failed to get required machine info.");
286     return;
287   }
288   value.SetString("system_hwqual", system_hwqual);
289   value.SetString("system_serial", serial_number);
290   value.SetString("os_language", g_browser_process->GetApplicationLocale());
291   value.SetString("os_name", kOSName);
292   value.SetString("os_version", version_);
293   value.SetString("os_connection", GetConnectionType());
294   value.SetString("user_email", "");
295 
296   // Optional info.
297   value.SetString("user_first_name", "");
298   value.SetString("user_last_name", "");
299 
300   web_ui_->CallJavascriptFunction(kJsApiSetUserInfo, value);
301 #endif
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 //
306 // RegisterPageUI
307 //
308 ////////////////////////////////////////////////////////////////////////////////
309 
RegisterPageUI(TabContents * contents)310 RegisterPageUI::RegisterPageUI(TabContents* contents) : WebUI(contents){
311   RegisterPageHandler* handler = new RegisterPageHandler();
312   AddMessageHandler((handler)->Attach(this));
313   handler->Init();
314   RegisterPageUIHTMLSource* html_source = new RegisterPageUIHTMLSource();
315 
316   // Set up the chrome://register/ source.
317   contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
318 }
319