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/choose_mobile_network_ui.h"
      6 
      7 #include <set>
      8 #include <string>
      9 
     10 #include "base/logging.h"
     11 #include "base/string_number_conversions.h"
     12 #include "base/string_piece.h"
     13 #include "base/values.h"
     14 #include "chrome/browser/chromeos/cros/cros_library.h"
     15 #include "chrome/browser/chromeos/cros/network_library.h"
     16 #include "chrome/browser/profiles/profile.h"
     17 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
     18 #include "chrome/common/jstemplate_builder.h"
     19 #include "chrome/common/url_constants.h"
     20 #include "content/browser/browser_thread.h"
     21 #include "content/browser/tab_contents/tab_contents.h"
     22 #include "grit/browser_resources.h"
     23 #include "grit/generated_resources.h"
     24 #include "ui/base/l10n/l10n_util.h"
     25 #include "ui/base/resource/resource_bundle.h"
     26 
     27 namespace chromeos {
     28 
     29 namespace {
     30 
     31 // JS API callbacks names.
     32 const char kJsApiCancel[] = "cancel";
     33 const char kJsApiConnect[] = "connect";
     34 
     35 // Page JS API function names.
     36 const char kJsApiShowNetworks[] = "mobile.ChooseNetwork.showNetworks";
     37 
     38 // Network properties.
     39 const char kNetworkIdProperty[] = "networkId";
     40 const char kOperatorNameProperty[] = "operatorName";
     41 const char kStatusProperty[] = "status";
     42 const char kTechnologyProperty[] = "technology";
     43 
     44 class ChooseMobileNetworkHTMLSource
     45     : public ChromeURLDataManager::DataSource {
     46  public:
     47   ChooseMobileNetworkHTMLSource();
     48 
     49   // Called when the network layer has requested a resource underneath
     50   // the path we registered.
     51   virtual void StartDataRequest(const std::string& path,
     52                                 bool is_incognito,
     53                                 int request_id);
     54   virtual std::string GetMimeType(const std::string&) const {
     55     return "text/html";
     56   }
     57 
     58  private:
     59   virtual ~ChooseMobileNetworkHTMLSource() {}
     60 
     61   std::string service_path_;
     62   DISALLOW_COPY_AND_ASSIGN(ChooseMobileNetworkHTMLSource);
     63 };
     64 
     65 class ChooseMobileNetworkHandler
     66     : public WebUIMessageHandler,
     67       public NetworkLibrary::NetworkDeviceObserver {
     68  public:
     69   ChooseMobileNetworkHandler();
     70   virtual ~ChooseMobileNetworkHandler();
     71 
     72   // WebUIMessageHandler implementation.
     73   virtual void RegisterMessages();
     74 
     75   // NetworkDeviceObserver implementation.
     76   virtual void OnNetworkDeviceChanged(NetworkLibrary* cros,
     77                                       const NetworkDevice* device);
     78 
     79  private:
     80   // Handlers for JS WebUI messages.
     81   void HandleCancel(const ListValue* args);
     82   void HandleConnect(const ListValue* args);
     83 
     84   std::string device_path_;
     85 
     86   DISALLOW_COPY_AND_ASSIGN(ChooseMobileNetworkHandler);
     87 };
     88 
     89 // ChooseMobileNetworkHTMLSource implementation.
     90 
     91 ChooseMobileNetworkHTMLSource::ChooseMobileNetworkHTMLSource()
     92     : DataSource(chrome::kChromeUIChooseMobileNetworkHost,
     93                  MessageLoop::current()) {
     94 }
     95 
     96 void ChooseMobileNetworkHTMLSource::StartDataRequest(const std::string& path,
     97                                                        bool is_incognito,
     98                                                        int request_id) {
     99   DictionaryValue strings;
    100   strings.SetString(
    101       "chooseNetworkTitle",
    102       l10n_util::GetStringUTF16(IDS_NETWORK_CHOOSE_MOBILE_NETWORK));
    103   strings.SetString(
    104       "scanningMsgLine1",
    105       l10n_util::GetStringUTF16(IDS_NETWORK_SCANNING_FOR_MOBILE_NETWORKS));
    106   strings.SetString(
    107       "scanningMsgLine2",
    108       l10n_util::GetStringUTF16(IDS_NETWORK_SCANNING_THIS_MAY_TAKE_A_MINUTE));
    109   strings.SetString(
    110       "noMobileNetworks",
    111       l10n_util::GetStringUTF16(IDS_NETWORK_NO_MOBILE_NETWORKS));
    112   strings.SetString("connect",
    113                     l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONNECT));
    114   strings.SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL));
    115   SetFontAndTextDirection(&strings);
    116 
    117   static const base::StringPiece html(
    118       ResourceBundle::GetSharedInstance().GetRawDataResource(
    119           IDR_CHOOSE_MOBILE_NETWORK_HTML));
    120 
    121   const std::string& full_html = jstemplate_builder::GetI18nTemplateHtml(
    122       html, &strings);
    123 
    124   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes());
    125   html_bytes->data.resize(full_html.size());
    126   std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
    127 
    128   SendResponse(request_id, html_bytes);
    129 }
    130 
    131 // ChooseMobileNetworkHandler implementation.
    132 
    133 ChooseMobileNetworkHandler::ChooseMobileNetworkHandler() {
    134   if (!CrosLibrary::Get()->EnsureLoaded())
    135     return;
    136 
    137   NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
    138   cros->RequestCellularScan();
    139   if (const NetworkDevice* cellular = cros->FindCellularDevice()) {
    140     device_path_ = cellular->device_path();
    141     cros->AddNetworkDeviceObserver(device_path_, this);
    142   }
    143 }
    144 
    145 ChooseMobileNetworkHandler::~ChooseMobileNetworkHandler() {
    146   if (!device_path_.empty()) {
    147     NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
    148     cros->RemoveNetworkDeviceObserver(device_path_, this);
    149   }
    150 }
    151 
    152 void ChooseMobileNetworkHandler::RegisterMessages() {
    153   web_ui_->RegisterMessageCallback(
    154       kJsApiCancel,
    155       NewCallback(this, &ChooseMobileNetworkHandler::HandleCancel));
    156   web_ui_->RegisterMessageCallback(
    157       kJsApiConnect,
    158       NewCallback(this, &ChooseMobileNetworkHandler::HandleConnect));
    159 }
    160 
    161 void ChooseMobileNetworkHandler::OnNetworkDeviceChanged(
    162     NetworkLibrary* cros,
    163     const NetworkDevice* device) {
    164 
    165   ListValue networks_list;
    166   std::set<std::string> network_ids;
    167   const CellularNetworkList& found_networks = device->found_cellular_networks();
    168   for (CellularNetworkList::const_iterator it = found_networks.begin();
    169        it != found_networks.end(); ++it) {
    170     // We need to remove duplicates from the list because same network with
    171     // different technologies are listed multiple times. But ModemManager
    172     // Register API doesn't allow technology to be specified so just show unique
    173     // network in UI.
    174     if (network_ids.insert(it->network_id).second) {
    175       DictionaryValue* network = new DictionaryValue();
    176       network->SetString(kNetworkIdProperty, it->network_id);
    177       if (!it->long_name.empty())
    178         network->SetString(kOperatorNameProperty, it->long_name);
    179       else if (!it->short_name.empty())
    180         network->SetString(kOperatorNameProperty, it->short_name);
    181       else
    182         network->SetString(kOperatorNameProperty, it->network_id);
    183       network->SetString(kStatusProperty, it->status);
    184       network->SetString(kTechnologyProperty, it->technology);
    185       networks_list.Append(network);
    186     }
    187   }
    188   web_ui_->CallJavascriptFunction(kJsApiShowNetworks, networks_list);
    189 }
    190 
    191 void ChooseMobileNetworkHandler::HandleCancel(const ListValue* args) {
    192   const size_t kConnectParamCount = 0;
    193   if (args->GetSize() != kConnectParamCount) {
    194     NOTREACHED();
    195     return;
    196   }
    197 
    198   if (!CrosLibrary::Get()->EnsureLoaded())
    199     return;
    200 
    201   // Switch to automatic mode.
    202   NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
    203   cros->RequestCellularRegister(std::string());
    204 }
    205 
    206 void ChooseMobileNetworkHandler::HandleConnect(const ListValue* args) {
    207   std::string network_id;
    208   const size_t kConnectParamCount = 1;
    209   if (args->GetSize() != kConnectParamCount ||
    210       !args->GetString(0, &network_id)) {
    211     NOTREACHED();
    212     return;
    213   }
    214 
    215   if (!CrosLibrary::Get()->EnsureLoaded())
    216     return;
    217 
    218   NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
    219   cros->RequestCellularRegister(network_id);
    220 }
    221 
    222 }  // namespace
    223 
    224 ChooseMobileNetworkUI::ChooseMobileNetworkUI(TabContents* contents)
    225     : WebUI(contents) {
    226   ChooseMobileNetworkHandler* handler = new ChooseMobileNetworkHandler();
    227   AddMessageHandler((handler)->Attach(this));
    228   ChooseMobileNetworkHTMLSource* html_source =
    229       new ChooseMobileNetworkHTMLSource();
    230   // Set up the "chrome://choose-mobile-network" source.
    231   contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
    232 }
    233 
    234 }  // namespace chromeos
    235