network_menu.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2010 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/chromeos/status/network_menu.h"
6
7#include "app/l10n_util.h"
8#include "app/resource_bundle.h"
9#include "base/command_line.h"
10#include "base/stringprintf.h"
11#include "base/utf_string_conversions.h"
12#include "chrome/browser/browser.h"
13#include "chrome/browser/browser_list.h"
14#include "chrome/browser/chromeos/cros/cros_library.h"
15#include "chrome/browser/chromeos/dom_ui/network_menu_ui.h"
16#include "chrome/common/chrome_switches.h"
17#include "chrome/common/url_constants.h"
18#include "chrome/browser/views/window.h"
19#include "gfx/canvas_skia.h"
20#include "gfx/skbitmap_operations.h"
21#include "grit/generated_resources.h"
22#include "grit/theme_resources.h"
23#include "net/base/escape.h"
24#include "views/controls/menu/menu_2.h"
25#include "views/window/window.h"
26
27namespace {
28// Constants passed to Javascript:
29static const char* kNetworkTypeEthernet = "ethernet";
30static const char* kNetworkTypeWifi = "wifi";
31static const char* kNetworkTypeCellular = "cellular";
32static const char* kNetworkTypeOther = "other";
33
34static const char* kNetworkStatusConnected = "connected";
35static const char* kNetworkStatusConnecting = "connecting";
36static const char* kNetworkStatusDisconnected = "disconnected";
37static const char* kNetworkStatusError = "error";
38}
39
40namespace chromeos {
41
42////////////////////////////////////////////////////////////////////////////////
43// NetworkMenu
44
45// static
46const int NetworkMenu::kNumWifiImages = 9;
47
48// NOTE: Use an array rather than just calculating a resource number to avoid
49// creating implicit ordering dependencies on the resource values.
50// static
51const int NetworkMenu::kBarsImages[kNumWifiImages] = {
52  IDR_STATUSBAR_NETWORK_BARS1,
53  IDR_STATUSBAR_NETWORK_BARS2,
54  IDR_STATUSBAR_NETWORK_BARS3,
55  IDR_STATUSBAR_NETWORK_BARS4,
56  IDR_STATUSBAR_NETWORK_BARS5,
57  IDR_STATUSBAR_NETWORK_BARS6,
58  IDR_STATUSBAR_NETWORK_BARS7,
59  IDR_STATUSBAR_NETWORK_BARS8,
60  IDR_STATUSBAR_NETWORK_BARS9,
61};
62// static
63const int NetworkMenu::kBarsImagesBlack[kNumWifiImages] = {
64  IDR_STATUSBAR_NETWORK_BARS1_BLACK,
65  IDR_STATUSBAR_NETWORK_BARS2_BLACK,
66  IDR_STATUSBAR_NETWORK_BARS3_BLACK,
67  IDR_STATUSBAR_NETWORK_BARS4_BLACK,
68  IDR_STATUSBAR_NETWORK_BARS5_BLACK,
69  IDR_STATUSBAR_NETWORK_BARS6_BLACK,
70  IDR_STATUSBAR_NETWORK_BARS7_BLACK,
71  IDR_STATUSBAR_NETWORK_BARS8_BLACK,
72  IDR_STATUSBAR_NETWORK_BARS9_BLACK,
73};
74// static
75const int NetworkMenu::kBarsImagesLowData[kNumWifiImages] = {
76  IDR_STATUSBAR_NETWORK_BARS1_LOWDATA,
77  IDR_STATUSBAR_NETWORK_BARS2_LOWDATA,
78  IDR_STATUSBAR_NETWORK_BARS3_LOWDATA,
79  IDR_STATUSBAR_NETWORK_BARS4_LOWDATA,
80  IDR_STATUSBAR_NETWORK_BARS5_LOWDATA,
81  IDR_STATUSBAR_NETWORK_BARS6_LOWDATA,
82  IDR_STATUSBAR_NETWORK_BARS7_LOWDATA,
83  IDR_STATUSBAR_NETWORK_BARS8_LOWDATA,
84  IDR_STATUSBAR_NETWORK_BARS9_LOWDATA,
85};
86// static
87const int NetworkMenu::kBarsImagesVLowData[kNumWifiImages] = {
88  IDR_STATUSBAR_NETWORK_BARS1_VLOWDATA,
89  IDR_STATUSBAR_NETWORK_BARS2_VLOWDATA,
90  IDR_STATUSBAR_NETWORK_BARS3_VLOWDATA,
91  IDR_STATUSBAR_NETWORK_BARS4_VLOWDATA,
92  IDR_STATUSBAR_NETWORK_BARS5_VLOWDATA,
93  IDR_STATUSBAR_NETWORK_BARS6_VLOWDATA,
94  IDR_STATUSBAR_NETWORK_BARS7_VLOWDATA,
95  IDR_STATUSBAR_NETWORK_BARS8_VLOWDATA,
96  IDR_STATUSBAR_NETWORK_BARS9_VLOWDATA,
97};
98
99NetworkMenu::NetworkMenu()
100    : min_width_(-1) {
101  network_menu_.reset(NetworkMenuUI::CreateMenu2(this));
102}
103
104NetworkMenu::~NetworkMenu() {
105}
106
107bool NetworkMenu::GetNetworkAt(int index, NetworkInfo* info) const {
108  DCHECK(info);
109  bool res = true;  // True unless a network doesn't exist.
110  int flags = menu_items_[index].flags;
111  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
112  if (flags & FLAG_ETHERNET) {
113    info->network_type = kNetworkTypeEthernet;
114    if (cros->ethernet_connected()) {
115      info->status = kNetworkStatusConnected;
116      info->ip_address = cros->ethernet_network().ip_address();
117    }
118    info->need_passphrase = false;
119    info->remembered = true;
120  } else if (flags & FLAG_WIFI) {
121    WifiNetwork wifi;
122    bool found = cros->FindWifiNetworkByPath(
123        menu_items_[index].wireless_path, &wifi);
124    if (found) {
125      info->network_type = kNetworkTypeWifi;
126      if (wifi.service_path() == cros->wifi_network().service_path()) {
127        if (cros->wifi_connected()) {
128          info->status = kNetworkStatusConnected;
129          info->message = l10n_util::GetStringUTF8(
130              IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED);
131        } else if (cros->wifi_connecting()) {
132          info->status = kNetworkStatusConnecting;
133          // TODO(stevenjb): Eliminate status message, or localize properly.
134          info->message = l10n_util::GetStringUTF8(
135              IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)
136              + ": " + wifi.GetStateString();
137        } else if (wifi.state() == STATE_FAILURE) {
138          info->status = kNetworkStatusError;
139          info->message = wifi.GetErrorString();
140        } else {
141          info->status = kNetworkStatusDisconnected;
142          info->message = l10n_util::GetStringUTF8(
143              IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED);
144        }
145      } else {
146        info->status = kNetworkStatusDisconnected;
147        info->message = l10n_util::GetStringUTF8(
148            IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED);
149      }
150      if (wifi.encrypted()) {
151        if (wifi.IsCertificateLoaded() ||
152            wifi.encryption() == SECURITY_8021X) {
153          info->need_passphrase = false;
154        } else {
155          info->need_passphrase = true;
156        }
157      } else {
158        info->need_passphrase = false;
159      }
160      info->ip_address = wifi.ip_address();
161      info->remembered = wifi.favorite();
162    } else {
163      res = false;  // Network not found, hide entry.
164    }
165  } else if (flags & FLAG_CELLULAR) {
166    CellularNetwork cellular;
167    bool found = cros->FindCellularNetworkByPath(
168        menu_items_[index].wireless_path, &cellular);
169    if (found) {
170      info->network_type = kNetworkTypeCellular;
171      if (cellular.service_path() ==
172          cros->cellular_network().service_path()) {
173        if (cros->cellular_connected()) {
174          info->status = kNetworkStatusConnected;
175          info->message = l10n_util::GetStringUTF8(
176              IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED);
177        } else if (cros->cellular_connecting()) {
178          // TODO(stevenjb): Eliminate status message, or localize properly.
179          info->status = kNetworkStatusConnecting;
180          info->message = l10n_util::GetStringUTF8(
181              IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)
182              + ": " + cellular.GetStateString();
183        } else if (cellular.state() == STATE_FAILURE) {
184          info->status = kNetworkStatusError;
185          info->message = cellular.GetErrorString();
186        } else {
187          info->status = kNetworkStatusDisconnected;
188          info->message = l10n_util::GetStringUTF8(
189              IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED);
190        }
191      } else {
192        info->status = kNetworkStatusDisconnected;
193        info->message = l10n_util::GetStringUTF8(
194            IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED);
195      }
196      info->ip_address = cellular.ip_address();
197      info->need_passphrase = false;
198      info->remembered = true;
199    } else {
200      res = false;  // Network not found, hide entry.
201    }
202  } else if (flags & FLAG_OTHER_NETWORK) {
203    info->status = kNetworkStatusDisconnected;
204    info->message = l10n_util::GetStringUTF8(
205        IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED);
206    info->network_type = kNetworkTypeOther;
207    info->need_passphrase = true;
208    info->remembered = true;
209  } else {
210    // Not a network, e.g options, separator.
211  }
212  return res;
213}
214
215bool NetworkMenu::ConnectToNetworkAt(int index,
216                                     const std::string& passphrase,
217                                     const std::string& ssid,
218                                     int remember) const {
219  int flags = menu_items_[index].flags;
220  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
221  if (flags & FLAG_WIFI) {
222    WifiNetwork wifi;
223    bool found = cros->FindWifiNetworkByPath(
224        menu_items_[index].wireless_path, &wifi);
225    if (found) {
226      // Connect or reconnect.
227      if (remember >= 0)
228        wifi.set_favorite(remember ? true : false);
229      if (wifi.encrypted()) {
230        if (wifi.IsCertificateLoaded()) {
231          cros->ConnectToWifiNetwork(wifi, std::string(), std::string(),
232                                     wifi.cert_path());
233        } else if (wifi.encryption() == SECURITY_8021X) {
234          // Show the wifi settings/dialog to load/select a certificate.
235          ShowWifi(wifi, true);
236        } else {
237          cros->ConnectToWifiNetwork(wifi, passphrase, std::string(),
238                                     std::string());
239        }
240      } else {
241        cros->ConnectToWifiNetwork(wifi, std::string(), std::string(),
242                                   std::string());
243      }
244    }
245  } else if (flags & FLAG_CELLULAR) {
246    CellularNetwork cellular;
247    bool found = cros->FindCellularNetworkByPath(
248        menu_items_[index].wireless_path, &cellular);
249    if (found) {
250      // Connect or reconnect.
251      cros->ConnectToCellularNetwork(cellular);
252    }
253  } else if (flags & FLAG_OTHER_NETWORK) {
254    bool favorite = remember == 0 ? false : true;  // default is true
255    cros->ConnectToWifiNetwork(ssid, passphrase, std::string(), std::string(),
256                               favorite);
257  }
258  return true;
259}
260
261////////////////////////////////////////////////////////////////////////////////
262// NetworkMenu, menus::MenuModel implementation:
263
264int NetworkMenu::GetItemCount() const {
265  return static_cast<int>(menu_items_.size());
266}
267
268menus::MenuModel::ItemType NetworkMenu::GetTypeAt(int index) const {
269  return menu_items_[index].type;
270}
271
272string16 NetworkMenu::GetLabelAt(int index) const {
273  return menu_items_[index].label;
274}
275
276const gfx::Font* NetworkMenu::GetLabelFontAt(int index) const {
277  return (menu_items_[index].flags & FLAG_ASSOCIATED) ?
278      &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) :
279      NULL;
280}
281
282bool NetworkMenu::IsItemCheckedAt(int index) const {
283  // All menus::MenuModel::TYPE_CHECK menu items are checked.
284  return true;
285}
286
287bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) const {
288  if (!menu_items_[index].icon.empty()) {
289    *icon = menu_items_[index].icon;
290    return true;
291  }
292  return false;
293}
294
295bool NetworkMenu::IsEnabledAt(int index) const {
296  return !(menu_items_[index].flags & FLAG_DISABLED);
297}
298
299void NetworkMenu::ActivatedAt(int index) {
300  // When we are refreshing the menu, ignore menu item activation.
301  if (refreshing_menu_)
302    return;
303
304  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
305  int flags = menu_items_[index].flags;
306  if (flags & FLAG_OPTIONS) {
307    OpenButtonOptions();
308  } else if (flags & FLAG_TOGGLE_ETHERNET) {
309    cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled());
310  } else if (flags & FLAG_TOGGLE_WIFI) {
311    cros->EnableWifiNetworkDevice(!cros->wifi_enabled());
312  } else if (flags & FLAG_TOGGLE_CELLULAR) {
313    cros->EnableCellularNetworkDevice(!cros->cellular_enabled());
314  } else if (flags & FLAG_TOGGLE_OFFLINE) {
315    cros->EnableOfflineMode(!cros->offline_mode());
316  } else if (flags & FLAG_OTHER_NETWORK) {
317    ShowOther();
318  } else if (flags & FLAG_ETHERNET) {
319    if (cros->ethernet_connected()) {
320      ShowEthernet(cros->ethernet_network());
321    }
322  } else if (flags & FLAG_WIFI) {
323    WifiNetwork wifi;
324    bool wifi_exists = cros->FindWifiNetworkByPath(
325        menu_items_[index].wireless_path, &wifi);
326    if (!wifi_exists) {
327      // If we are attempting to connect to a network that no longer exists,
328      // display a notification.
329      // TODO(stevenjb): Show notification.
330    } else if (wifi.service_path() == cros->wifi_network().service_path()) {
331      // Show the config settings for the active network.
332      ShowWifi(wifi, false);
333    } else {
334      ConnectToNetworkAt(index, std::string(), std::string(), -1);
335    }
336  } else if (flags & FLAG_CELLULAR) {
337    CellularNetwork cellular;
338    bool cellular_exists = cros->FindCellularNetworkByPath(
339        menu_items_[index].wireless_path, &cellular);
340    if (!cellular_exists) {
341      // If we are attempting to connect to a network that no longer exists,
342      // display a notification.
343      // TODO(stevenjb): Show notification.
344    } else if (cellular.service_path() ==
345               cros->cellular_network().service_path()) {
346      // Show the config settings for the cellular network.
347      ShowCellular(cellular, false);
348    } else {
349      ConnectToNetworkAt(index, std::string(), std::string(), -1);
350    }
351  }
352}
353
354void NetworkMenu::SetFirstLevelMenuWidth(int width) {
355  min_width_ = width;
356  // This actually has no effect since menu is rebuilt before showing.
357  network_menu_->SetMinimumWidth(width);
358}
359
360void NetworkMenu::CancelMenu() {
361  network_menu_->CancelMenu();
362}
363
364void NetworkMenu::UpdateMenu() {
365  refreshing_menu_ = true;
366  InitMenuItems();
367  network_menu_->Rebuild();
368  refreshing_menu_ = false;
369}
370
371// static
372SkBitmap NetworkMenu::IconForNetworkStrength(int strength, bool black) {
373  // Compose wifi icon by superimposing various icons.
374  int index = static_cast<int>(strength / 100.0 *
375      nextafter(static_cast<float>(kNumWifiImages), 0));
376  index = std::max(std::min(index, kNumWifiImages - 1), 0);
377  const int* images = black ? kBarsImagesBlack : kBarsImages;
378  return *ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]);
379}
380
381SkBitmap NetworkMenu::IconForNetworkStrength(CellularNetwork cellular) {
382  // Compose wifi icon by superimposing various icons.
383  int index = static_cast<int>(cellular.strength() / 100.0 *
384      nextafter(static_cast<float>(kNumWifiImages), 0));
385  index = std::max(std::min(index, kNumWifiImages - 1), 0);
386  const int* images = kBarsImages;
387  switch (cellular.data_left()) {
388    case CellularNetwork::DATA_NONE:
389    case CellularNetwork::DATA_VERY_LOW:
390      images = kBarsImagesVLowData;
391      break;
392    case CellularNetwork::DATA_LOW:
393      images = kBarsImagesLowData;
394      break;
395    case CellularNetwork::DATA_NORMAL:
396      images = kBarsImages;
397      break;
398  }
399  return *ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]);
400}
401
402// static
403SkBitmap NetworkMenu::IconForDisplay(SkBitmap icon, SkBitmap badge) {
404  // Icons are 24x24.
405  static const int kIconWidth = 24;
406  static const int kIconHeight = 24;
407  // Draw the network icon 3 pixels down to center it.
408  static const int kIconX = 0;
409  static const int kIconY = 3;
410  // Draw badge at (14,14).
411  static const int kBadgeX = 14;
412  static const int kBadgeY = 14;
413
414  gfx::CanvasSkia canvas(kIconWidth, kIconHeight, false);
415  canvas.DrawBitmapInt(icon, kIconX, kIconY);
416  if (!badge.empty())
417    canvas.DrawBitmapInt(badge, kBadgeX, kBadgeY);
418  return canvas.ExtractBitmap();
419}
420
421////////////////////////////////////////////////////////////////////////////////
422// NetworkMenu, views::ViewMenuDelegate implementation:
423
424void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) {
425  refreshing_menu_ = true;
426  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
427  cros->RequestWifiScan();
428  cros->UpdateSystemInfo();
429  InitMenuItems();
430  network_menu_->Rebuild();
431  // Restore menu width, if it was set up.
432  // NOTE: width isn't checked for correctness here since all width-related
433  // logic implemented inside |network_menu_|.
434  if (min_width_ != -1)
435    network_menu_->SetMinimumWidth(min_width_);
436  refreshing_menu_ = false;
437  network_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
438}
439
440void NetworkMenu::InitMenuItems() {
441  // This gets called on initialization, so any changes should be reflected
442  // in CrosMock::SetNetworkLibraryStatusAreaExpectations().
443
444  menu_items_.clear();
445  // Populate our MenuItems with the current list of wifi networks.
446  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
447  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
448
449  // Ethernet
450  bool ethernet_connected = cros->ethernet_connected();
451  bool ethernet_connecting = cros->ethernet_connecting();
452  string16 label = l10n_util::GetStringUTF16(
453                       IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
454  SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK);
455  SkBitmap badge = ethernet_connecting || ethernet_connected ?
456      SkBitmap() : *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED);
457  int flag = FLAG_ETHERNET;
458  if (ethernet_connecting || ethernet_connected)
459    flag |= FLAG_ASSOCIATED;
460  menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
461      IconForDisplay(icon, badge), std::string(), flag));
462
463  // Wifi
464  const WifiNetworkVector& wifi_networks = cros->wifi_networks();
465  const WifiNetwork& active_wifi = cros->wifi_network();
466  // Wifi networks ssids.
467  for (size_t i = 0; i < wifi_networks.size(); ++i) {
468    label = ASCIIToUTF16(wifi_networks[i].name());
469    SkBitmap icon = IconForNetworkStrength(wifi_networks[i].strength(), true);
470    SkBitmap badge = wifi_networks[i].encrypted() ?
471        *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : SkBitmap();
472    flag = FLAG_WIFI;
473    if (wifi_networks[i].service_path() == active_wifi.service_path())
474      flag |= FLAG_ASSOCIATED;
475    menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
476        IconForDisplay(icon, badge), wifi_networks[i].service_path(), flag));
477  }
478
479  // Cellular
480  const CellularNetworkVector& cell_networks = cros->cellular_networks();
481  const CellularNetwork& active_cellular = cros->cellular_network();
482  // Cellular networks ssids.
483  for (size_t i = 0; i < cell_networks.size(); ++i) {
484    label = ASCIIToUTF16(cell_networks[i].name());
485    SkBitmap icon = IconForNetworkStrength(cell_networks[i].strength(), true);
486    // TODO(chocobo): Check cellular network 3g/edge.
487    SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_3G);
488//    SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_EDGE);
489    flag = FLAG_CELLULAR;
490    if (cell_networks[i].service_path() == active_cellular.service_path())
491      flag |= FLAG_ASSOCIATED;
492    menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
493        IconForDisplay(icon, badge), cell_networks[i].service_path(), flag));
494  }
495
496  // No networks available message.
497  if (wifi_networks.empty() && cell_networks.empty()) {
498    label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT,
499                l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE));
500    menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
501        SkBitmap(), std::string(), FLAG_DISABLED));
502  }
503
504  // Other networks
505  menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND,
506      l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_NETWORKS),
507      IconForDisplay(*rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0),
508                     SkBitmap()),
509      std::string(), FLAG_OTHER_NETWORK));
510
511  bool wifi_available = cros->wifi_available();
512  bool cellular_available = cros->cellular_available();
513  if (wifi_available || cellular_available) {
514    // Separator.
515    menu_items_.push_back(MenuItem());
516
517    // Turn Wifi Off. (only if wifi available)
518    if (wifi_available) {
519      int id = cros->wifi_enabled() ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE :
520                                      IDS_STATUSBAR_NETWORK_DEVICE_ENABLE;
521      label = l10n_util::GetStringFUTF16(id,
522          l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI));
523      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
524          SkBitmap(), std::string(), FLAG_TOGGLE_WIFI));
525    }
526
527    // Turn Cellular Off. (only if cellular available)
528    if (cellular_available) {
529      int id = cros->cellular_enabled() ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE :
530                                      IDS_STATUSBAR_NETWORK_DEVICE_ENABLE;
531      label = l10n_util::GetStringFUTF16(id,
532          l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CELLULAR));
533      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
534          SkBitmap(), std::string(), FLAG_TOGGLE_CELLULAR));
535    }
536  }
537
538  // TODO(chocobo): Uncomment once we figure out how to do offline mode.
539  // Offline mode.
540//  menu_items_.push_back(MenuItem(cros->offline_mode() ?
541//      menus::MenuModel::TYPE_CHECK : menus::MenuModel::TYPE_COMMAND,
542//      l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OFFLINE_MODE),
543//      SkBitmap(), std::string(), FLAG_TOGGLE_OFFLINE));
544
545  if (cros->Connected() || ShouldOpenButtonOptions()) {
546    // Separator.
547    menu_items_.push_back(MenuItem());
548
549    // Network settings.
550    if (ShouldOpenButtonOptions()) {
551      label =
552          l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OPEN_OPTIONS_DIALOG);
553      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
554          SkBitmap(), std::string(), FLAG_OPTIONS));
555    }
556  }
557}
558
559void NetworkMenu::ShowTabbedNetworkSettings(const Network& network) const {
560  Browser* browser = BrowserList::GetLastActive();
561  if (!browser)
562    return;
563  std::string page = StringPrintf("%s?servicePath=%s&networkType=%d",
564      chrome::kInternetOptionsSubPage,
565      EscapeUrlEncodedData(network.service_path()).c_str(),
566      network.type());
567  browser->ShowOptionsTab(page);
568}
569
570// TODO(stevenjb): deprecate this once we've committed to the embedded
571// menu UI and fully deprecated NetworkConfigView.
572void NetworkMenu::ShowNetworkConfigView(NetworkConfigView* view,
573                                        bool focus_login) const {
574  view->set_browser_mode(IsBrowserMode());
575  views::Window* window = browser::CreateViewsWindow(
576      GetNativeWindow(), gfx::Rect(), view);
577  window->SetIsAlwaysOnTop(true);
578  window->Show();
579  if (focus_login)
580    view->SetLoginTextfieldFocus();
581}
582
583void NetworkMenu::ShowWifi(const WifiNetwork& wifi, bool focus_login) const{
584  if (CommandLine::ForCurrentProcess()->HasSwitch(
585          switches::kEnableTabbedOptions)) {
586    ShowTabbedNetworkSettings(wifi);
587  } else {
588    ShowNetworkConfigView(new NetworkConfigView(wifi, true), focus_login);
589  }
590}
591
592void NetworkMenu::ShowCellular(const CellularNetwork& cellular,
593                               bool focus_login) const {
594  if (CommandLine::ForCurrentProcess()->HasSwitch(
595          switches::kEnableTabbedOptions)) {
596    ShowTabbedNetworkSettings(cellular);
597  } else {
598    ShowNetworkConfigView(new NetworkConfigView(cellular), focus_login);
599  }
600}
601
602void NetworkMenu::ShowEthernet(const EthernetNetwork& ethernet) const {
603  if (CommandLine::ForCurrentProcess()->HasSwitch(
604          switches::kEnableTabbedOptions)) {
605    ShowTabbedNetworkSettings(ethernet);
606  } else {
607    ShowNetworkConfigView(new NetworkConfigView(ethernet), false);
608  }
609}
610
611void NetworkMenu::ShowOther() const {
612  if (CommandLine::ForCurrentProcess()->HasSwitch(
613          switches::kEnableTabbedOptions)) {
614    Browser* browser = BrowserList::GetLastActive();
615    if (browser) {
616      std::string page = StringPrintf("%s?networkType=%d",
617                                      chrome::kInternetOptionsSubPage,
618                                      chromeos::TYPE_WIFI);
619      browser->ShowOptionsTab(page);
620    }
621  } else {
622    const bool kFocusLogin = true;
623    ShowNetworkConfigView(new NetworkConfigView(), kFocusLogin);
624  }
625}
626
627}  // namespace chromeos
628