Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / choose_mobile_network_ui.cc
1 // Copyright (c) 2012 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/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h"
16 #include "base/values.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/url_constants.h"
19 #include "chrome/grit/generated_resources.h"
20 #include "chromeos/network/device_state.h"
21 #include "chromeos/network/network_device_handler.h"
22 #include "chromeos/network/network_event_log.h"
23 #include "chromeos/network/network_state_handler.h"
24 #include "chromeos/network/network_state_handler_observer.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/browser/web_ui.h"
27 #include "content/public/browser/web_ui_data_source.h"
28 #include "content/public/browser/web_ui_message_handler.h"
29 #include "grit/browser_resources.h"
30 #include "third_party/cros_system_api/dbus/service_constants.h"
31
32 using content::WebContents;
33 using content::WebUIMessageHandler;
34
35 namespace chromeos {
36
37 namespace {
38
39 // JS API callbacks names.
40 const char kJsApiCancel[] = "cancel";
41 const char kJsApiConnect[] = "connect";
42 const char kJsApiPageReady[] = "pageReady";
43
44 // Page JS API function names.
45 const char kJsApiShowNetworks[] = "mobile.ChooseNetwork.showNetworks";
46 const char kJsApiShowScanning[] = "mobile.ChooseNetwork.showScanning";
47
48 // Network properties.
49 const char kNetworkIdProperty[] = "networkId";
50 const char kOperatorNameProperty[] = "operatorName";
51 const char kStatusProperty[] = "status";
52 const char kTechnologyProperty[] = "technology";
53
54 content::WebUIDataSource* CreateChooseMobileNetworkUIHTMLSource() {
55   content::WebUIDataSource* source = content::WebUIDataSource::Create(
56       chrome::kChromeUIChooseMobileNetworkHost);
57
58   source->AddLocalizedString("chooseNetworkTitle",
59                              IDS_NETWORK_CHOOSE_MOBILE_NETWORK);
60   source->AddLocalizedString("scanningMsgLine1",
61                              IDS_NETWORK_SCANNING_FOR_MOBILE_NETWORKS);
62   source->AddLocalizedString("scanningMsgLine2",
63                              IDS_NETWORK_SCANNING_THIS_MAY_TAKE_A_MINUTE);
64   source->AddLocalizedString("noMobileNetworks",
65                              IDS_NETWORK_NO_MOBILE_NETWORKS);
66   source->AddLocalizedString("connect", IDS_OPTIONS_SETTINGS_CONNECT);
67   source->AddLocalizedString("cancel", IDS_CANCEL);
68
69   source->SetJsonPath("strings.js");
70   source->AddResourcePath("choose_mobile_network.js",
71                           IDR_CHOOSE_MOBILE_NETWORK_JS);
72   source->SetDefaultResource(IDR_CHOOSE_MOBILE_NETWORK_HTML);
73   return source;
74 }
75
76 chromeos::NetworkDeviceHandler* GetNetworkDeviceHandler() {
77   return chromeos::NetworkHandler::Get()->network_device_handler();
78 }
79
80 chromeos::NetworkStateHandler* GetNetworkStateHandler() {
81   return chromeos::NetworkHandler::Get()->network_state_handler();
82 }
83
84 void NetworkOperationErrorCallback(
85     const std::string& operation_name,
86     const std::string& error_name,
87     scoped_ptr<base::DictionaryValue> error_data) {
88   NET_LOG_ERROR("Operation failed: " + error_name, operation_name);
89 }
90
91 class ChooseMobileNetworkHandler
92     : public WebUIMessageHandler,
93       public NetworkStateHandlerObserver {
94  public:
95   ChooseMobileNetworkHandler();
96   virtual ~ChooseMobileNetworkHandler();
97
98   // WebUIMessageHandler implementation.
99   virtual void RegisterMessages() override;
100
101   // NetworkStateHandlerObserver implementation.
102   virtual void DeviceListChanged() override;
103
104  private:
105   // Handlers for JS WebUI messages.
106   void HandleCancel(const base::ListValue* args);
107   void HandleConnect(const base::ListValue* args);
108   void HandlePageReady(const base::ListValue* args);
109
110   std::string device_path_;
111   base::ListValue networks_list_;
112   bool is_page_ready_;
113   bool has_pending_results_;
114
115   DISALLOW_COPY_AND_ASSIGN(ChooseMobileNetworkHandler);
116 };
117
118 // ChooseMobileNetworkHandler implementation.
119
120 ChooseMobileNetworkHandler::ChooseMobileNetworkHandler()
121     : is_page_ready_(false),
122       has_pending_results_(false) {
123   NetworkStateHandler* handler = GetNetworkStateHandler();
124   const DeviceState* cellular =
125       handler->GetDeviceStateByType(NetworkTypePattern::Cellular());
126   if (!cellular) {
127     NET_LOG_ERROR(
128         "A cellular device is not available.",
129         "Cannot initiate a cellular network scan without a cellular device.");
130     return;
131   }
132   handler->AddObserver(this, FROM_HERE);
133   device_path_ = cellular->path();
134   GetNetworkDeviceHandler()->ProposeScan(
135       device_path_,
136       base::Bind(&base::DoNothing),
137       base::Bind(&NetworkOperationErrorCallback, "ProposeScan"));
138 }
139
140 ChooseMobileNetworkHandler::~ChooseMobileNetworkHandler() {
141   GetNetworkStateHandler()->RemoveObserver(this, FROM_HERE);
142 }
143
144 void ChooseMobileNetworkHandler::RegisterMessages() {
145   web_ui()->RegisterMessageCallback(
146       kJsApiCancel,
147       base::Bind(&ChooseMobileNetworkHandler::HandleCancel,
148                  base::Unretained(this)));
149   web_ui()->RegisterMessageCallback(
150       kJsApiConnect,
151       base::Bind(&ChooseMobileNetworkHandler::HandleConnect,
152                  base::Unretained(this)));
153   web_ui()->RegisterMessageCallback(
154       kJsApiPageReady,
155       base::Bind(&ChooseMobileNetworkHandler::HandlePageReady,
156                  base::Unretained(this)));
157 }
158
159 void ChooseMobileNetworkHandler::DeviceListChanged() {
160   const DeviceState* cellular = GetNetworkStateHandler()->GetDeviceState(
161       device_path_);
162   networks_list_.Clear();
163   if (!cellular) {
164     LOG(WARNING) << "Cellular device with path '" << device_path_
165                  << "' disappeared.";
166     return;
167   }
168   if (cellular->scanning()) {
169     NET_LOG_EVENT("ChooseMobileNetwork", "Device is scanning for networks.");
170     web_ui()->CallJavascriptFunction(kJsApiShowScanning);
171     return;
172   }
173   const DeviceState::CellularScanResults& scan_results =
174       cellular->scan_results();
175   std::set<std::string> network_ids;
176   for (DeviceState::CellularScanResults::const_iterator it =
177       scan_results.begin(); it != scan_results.end(); ++it) {
178     // We need to remove duplicates from the list because same network with
179     // different technologies are listed multiple times. But ModemManager
180     // Register API doesn't allow technology to be specified so just show unique
181     // network in UI.
182     if (network_ids.insert(it->network_id).second) {
183       base::DictionaryValue* network = new base::DictionaryValue();
184       network->SetString(kNetworkIdProperty, it->network_id);
185       if (!it->long_name.empty())
186         network->SetString(kOperatorNameProperty, it->long_name);
187       else if (!it->short_name.empty())
188         network->SetString(kOperatorNameProperty, it->short_name);
189       else
190         network->SetString(kOperatorNameProperty, it->network_id);
191       network->SetString(kStatusProperty, it->status);
192       network->SetString(kTechnologyProperty, it->technology);
193       networks_list_.Append(network);
194     }
195   }
196   if (is_page_ready_) {
197     web_ui()->CallJavascriptFunction(kJsApiShowNetworks, networks_list_);
198     networks_list_.Clear();
199     has_pending_results_ = false;
200   } else {
201     has_pending_results_ = true;
202   }
203 }
204
205 void ChooseMobileNetworkHandler::HandleCancel(const base::ListValue* args) {
206   const size_t kConnectParamCount = 0;
207   if (args->GetSize() != kConnectParamCount) {
208     NOTREACHED();
209     return;
210   }
211
212   // Switch to automatic mode.
213   GetNetworkDeviceHandler()->RegisterCellularNetwork(
214       device_path_,
215       "",  // An empty string is for registration with the home network.
216       base::Bind(&base::DoNothing),
217       base::Bind(&NetworkOperationErrorCallback,
218                  "Register in automatic mode."));
219 }
220
221 void ChooseMobileNetworkHandler::HandleConnect(const base::ListValue* args) {
222   std::string network_id;
223   const size_t kConnectParamCount = 1;
224   if (args->GetSize() != kConnectParamCount ||
225       !args->GetString(0, &network_id)) {
226     NOTREACHED();
227     return;
228   }
229
230   GetNetworkDeviceHandler()->RegisterCellularNetwork(
231       device_path_,
232       network_id,
233       base::Bind(&base::DoNothing),
234       base::Bind(&NetworkOperationErrorCallback,
235                  std::string("Register to network: ") + network_id));
236 }
237
238 void ChooseMobileNetworkHandler::HandlePageReady(const base::ListValue* args) {
239   const size_t kConnectParamCount = 0;
240   if (args->GetSize() != kConnectParamCount) {
241     NOTREACHED();
242     return;
243   }
244
245   if (has_pending_results_) {
246     web_ui()->CallJavascriptFunction(kJsApiShowNetworks, networks_list_);
247     networks_list_.Clear();
248     has_pending_results_ = false;
249   }
250   is_page_ready_ = true;
251 }
252
253 }  // namespace
254
255 ChooseMobileNetworkUI::ChooseMobileNetworkUI(content::WebUI* web_ui)
256     : WebUIController(web_ui) {
257   ChooseMobileNetworkHandler* handler = new ChooseMobileNetworkHandler();
258   web_ui->AddMessageHandler(handler);
259   // Set up the "chrome://choose-mobile-network" source.
260   Profile* profile = Profile::FromWebUI(web_ui);
261   content::WebUIDataSource::Add(
262       profile, CreateChooseMobileNetworkUIHTMLSource());
263 }
264
265 }  // namespace chromeos