Home | History | Annotate | Download | only in chromeos
      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)
     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);
    100   virtual std::string GetMimeType(const std::string&) const {
    101     return "text/html";
    102   }
    103 
    104  private:
    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 
    159 RegisterPageUIHTMLSource::RegisterPageUIHTMLSource()
    160     : DataSource(chrome::kChromeUIRegisterPageHost, MessageLoop::current()) {
    161 }
    162 
    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 ////////////////////////////////////////////////////////////////////////////////
    198 RegisterPageHandler::RegisterPageHandler() {
    199 }
    200 
    201 RegisterPageHandler::~RegisterPageHandler() {
    202 }
    203 
    204 WebUIMessageHandler* RegisterPageHandler::Attach(WebUI* web_ui) {
    205   return WebUIMessageHandler::Attach(web_ui);
    206 }
    207 
    208 void RegisterPageHandler::Init() {
    209 }
    210 
    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 
    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 
    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)
    256 void RegisterPageHandler::OnVersion(chromeos::VersionLoader::Handle handle,
    257                                     std::string version) {
    258   version_ = version;
    259   SendUserInfo();
    260 }
    261 #endif
    262 
    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 
    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 
    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