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