Refactor network selection screen. Add Ethernet network to the list.

BUG=35016
TEST=With --login-manager=network screen should be shown. Ethernet and Wifi networks are shown and could be selected.

Review URL: http://codereview.chromium.org/597046

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39064 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 050d147..dc91abd 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6858,7 +6858,13 @@
       </message>
       <message name="IDS_NETWORK_SELECTION_SELECT" desc="Label for network selection dropdown">
         Please select a network:
+      </message>            
+      <message name="IDS_NETWORK_SELECTION_NONE" desc="Text shown in combobox when no network are selected">
+        No selection
       </message>
+      <message name="IDS_NETWORK_SELECTION_OFFLINE_BUTTON" desc="Text shown on work offline button">
+        Work offline
+      </message>      
       <message name="IDS_LOGIN_TITLE">
         Sign in with your Google account
       </message>
diff --git a/chrome/browser/chromeos/login/login_manager_view.cc b/chrome/browser/chromeos/login/login_manager_view.cc
index 6ddd33c..0c8c37e 100644
--- a/chrome/browser/chromeos/login/login_manager_view.cc
+++ b/chrome/browser/chromeos/login/login_manager_view.cc
@@ -358,6 +358,12 @@
     Login();
     // Return true so that processing ends
     return true;
+  } else if (keystroke.GetKeyboardCode() == base::VKEY_ESCAPE) {
+    // TODO(nkostylev): Implement non-textfield dependent keystroke handler.
+    if (observer_) {
+      observer_->OnExit(chromeos::ScreenObserver::LOGIN_BACK);
+    }
+    return true;
   }
   // Return false so that processing does not end
   return false;
diff --git a/chrome/browser/chromeos/login/login_wizard_view.cc b/chrome/browser/chromeos/login/login_wizard_view.cc
index ea4f24f..e4ac6a03d 100644
--- a/chrome/browser/chromeos/login/login_wizard_view.cc
+++ b/chrome/browser/chromeos/login/login_wizard_view.cc
@@ -181,7 +181,6 @@
   if (start_view_name == kLoginManager) {
     current_ = login_manager_;
   } else if (start_view_name == kNetworkSelection) {
-    // TODO(nkostylev): Init network selection screen when it's required.
     current_ = network_selection_;
   } else if (start_view_name == kAccountCreation) {
     current_ = account_creation_;
@@ -200,6 +199,12 @@
   }
 }
 
+void LoginWizardView::OnLoginBack() {
+  // TODO(nkostylev): Do not fall back to welcome screen
+  // when known network is available.
+  SetCurrentScreen(network_selection_);
+}
+
 void LoginWizardView::OnNetworkConnected() {
   // TODO(avayvod): Switch to update screen when it's ready.
   SetCurrentScreen(login_manager_);
@@ -258,11 +263,14 @@
       OnLoginSignInSelected();
       break;
     case NETWORK_CONNECTED:
+    case NETWORK_OFFLINE:
       OnNetworkConnected();
       break;
     case ACCOUNT_CREATED:
       OnAccountCreated();
       break;
+    case LOGIN_BACK:
+      OnLoginBack();
     default:
       NOTREACHED();
   }
diff --git a/chrome/browser/chromeos/login/login_wizard_view.h b/chrome/browser/chromeos/login/login_wizard_view.h
index 6898c51fa..0a52b83 100644
--- a/chrome/browser/chromeos/login/login_wizard_view.h
+++ b/chrome/browser/chromeos/login/login_wizard_view.h
@@ -37,6 +37,7 @@
  private:
   // Exit handlers:
   void OnLoginSignInSelected();
+  void OnLoginBack();
   void OnNetworkConnected();
   void OnAccountCreated();
 
diff --git a/chrome/browser/chromeos/login/network_selection_view.cc b/chrome/browser/chromeos/login/network_selection_view.cc
index 2b6581f..1f72233 100644
--- a/chrome/browser/chromeos/login/network_selection_view.cc
+++ b/chrome/browser/chromeos/login/network_selection_view.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/chromeos/login/screen_observer.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
+#include "views/controls/button/native_button.h"
 #include "views/controls/combobox/combobox.h"
 #include "views/controls/label.h"
 #include "views/widget/widget.h"
@@ -27,14 +28,17 @@
 namespace {
 
 const int kCornerRadius = 12;
-const int kWelcomeLabelY = 200;
+const int kShadow = 10;
+const int kWelcomeLabelY = 150;
+const int kOfflineButtonX = 30;
 const int kSpacing = 25;
 const int kComboboxSpacing = 5;
 const int kHorizontalSpacing = 25;
 const int kNetworkComboboxWidth = 250;
 const int kNetworkComboboxHeight = 30;
-const SkColor kWelcomeColor = SK_ColorGRAY;
+const SkColor kWelcomeColor = 0x0054A4;
 const SkColor kBackground = SK_ColorWHITE;
+const SkColor kShadowColor = 0x40223673;
 
 }  // namespace
 
@@ -57,14 +61,17 @@
   // TODO(nkostylev): Add UI language and logo.
   // Use rounded rect background.
   views::Painter* painter = new chromeos::RoundedRectPainter(
-      0, kBackground,             // no padding
-      true, SK_ColorBLACK,        // black shadow
-      kCornerRadius,              // corner radius
-      kBackground, kBackground);  // background without gradient
-  set_background(views::Background::CreateBackgroundPainter(true, painter));
+       0, 0x00000000,              // no padding
+       kShadow, kShadowColor,      // gradient shadow
+       kCornerRadius,              // corner radius
+       kBackground, kBackground);  // backgound without gradient
+   set_background(
+       views::Background::CreateBackgroundPainter(true, painter));
+
   gfx::Font welcome_label_font =
-      gfx::Font::CreateFont(L"Droid Sans", 14).DeriveFont(0, gfx::Font::BOLD);
+      gfx::Font::CreateFont(L"Droid Sans", 20).DeriveFont(0, gfx::Font::BOLD);
   gfx::Font network_label_font = gfx::Font::CreateFont(L"Droid Sans", 9);
+  gfx::Font button_font = network_label_font;
 
   welcome_label_ = new views::Label();
   welcome_label_->SetColor(kWelcomeColor);
@@ -74,15 +81,17 @@
   select_network_label_->SetFont(network_label_font);
 
   network_combobox_ = new views::Combobox(this);
-  network_combobox_->SetSelectedItem(0);
   network_combobox_->set_listener(this);
 
+  offline_button_ = new views::NativeButton(this, std::wstring());
+  offline_button_->set_font(button_font);
+
   UpdateLocalizedStrings();
 
   AddChildView(welcome_label_);
   AddChildView(select_network_label_);
   AddChildView(network_combobox_);
-  NetworkChanged(chromeos::NetworkLibrary::Get());
+  AddChildView(offline_button_);
 }
 
 void NetworkSelectionView::UpdateLocalizedStrings() {
@@ -90,7 +99,9 @@
                           l10n_util::GetString(IDS_PRODUCT_OS_NAME)));
   select_network_label_->SetText(
       l10n_util::GetString(IDS_NETWORK_SELECTION_SELECT));
-  network_combobox_->ModelChanged();
+  offline_button_->SetLabel(
+      l10n_util::GetString(IDS_NETWORK_SELECTION_OFFLINE_BUTTON));
+  NetworkChanged(chromeos::NetworkLibrary::Get());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -123,6 +134,13 @@
   network_combobox_->SetBounds(x, y,
                                kNetworkComboboxWidth, kNetworkComboboxHeight);
 
+  y = height() - offline_button_->GetPreferredSize().height() - kSpacing;
+  offline_button_->SetBounds(
+      kOfflineButtonX,
+      y,
+      offline_button_->GetPreferredSize().width(),
+      offline_button_->GetPreferredSize().height());
+
   // Need to refresh combobox layout explicitly.
   network_combobox_->Layout();
   SchedulePaint();
@@ -139,18 +157,20 @@
 // ComboboxModel implementation:
 
 int NetworkSelectionView::GetItemCount() {
-  // Item count is always 1 more than number of networks.
-  return static_cast<int>(wifi_networks_.size()) + 1;
+  // Item with index = 0 is either "no networks are available" or
+  // "no selection".
+  return static_cast<int>(networks_.GetNetworkCount()) + 1;
 }
 
 std::wstring NetworkSelectionView::GetItemAt(int index) {
   if (index == 0) {
-    return wifi_networks_.empty() ?
+    return networks_.IsEmpty() ?
         l10n_util::GetString(IDS_STATUSBAR_NO_NETWORKS_MESSAGE) :
-        std::wstring();
+        l10n_util::GetString(IDS_NETWORK_SELECTION_NONE);
   }
-  // TODO(nkostylev): Sort networks (Ethernet, public WiFi, encrypted WiFi).
-  return ASCIIToWide(wifi_networks_[index-1].ssid);
+  chromeos::NetworkList::NetworkItem* network =
+      networks_.GetNetworkAt(index - 1);
+  return network ? UTF16ToWide(network->label) : std::wstring();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -159,42 +179,82 @@
 void NetworkSelectionView::ItemChanged(views::Combobox* sender,
                                        int prev_index,
                                        int new_index) {
-  if (new_index == prev_index)
+  if (new_index == prev_index || new_index < 0 || prev_index < 0)
     return;
 
-  // First item is empty.
+  // First item is a text, not a network.
   if (new_index == 0) {
     network_combobox_->SetSelectedItem(prev_index);
     return;
   }
 
-  if (!HasWifiNetworks())
+  if (networks_.IsEmpty())
     return;
 
-  chromeos::WifiNetwork selected_network = GetWifiNetworkAt(new_index);
-  if (selected_network.encrypted) {
-    // TODO(nkostylev): Show password dialog.
-  } else {
-    chromeos::NetworkLibrary::Get()->ConnectToWifiNetwork(selected_network,
-                                                          string16());
+  chromeos::NetworkList::NetworkItem* network =
+      networks_.GetNetworkAt(new_index - 1);
+  if (network) {
+    if (chromeos::NetworkList::NETWORK_WIFI == network->network_type) {
+      if (network->wifi_network.encrypted) {
+        OpenPasswordDialog(network->wifi_network);
+        return;
+      } else {
+        chromeos::NetworkLibrary::Get()->ConnectToWifiNetwork(
+            network->wifi_network, string16());
+      }
+    } else if (chromeos::NetworkList::NETWORK_CELLULAR ==
+               network->network_type) {
+      chromeos::NetworkLibrary::Get()->ConnectToCellularNetwork(
+          network->cellular_network);
+    }
+    // TODO(avayvod): Check for connection error.
+    NotifyOnConnection();
   }
-  // TODO(avayvod): Check for connection error.
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// views::ButtonListener implementation:
+void NetworkSelectionView::ButtonPressed(views::Button* sender,
+                                         const views::Event& event) {
   if (observer_) {
-    observer_->OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED);
+    observer_->OnExit(chromeos::ScreenObserver::NETWORK_OFFLINE);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// NetworkMenuButton, NetworkLibrary::Observer implementation:
+// PasswordDialogDelegate implementation:
 
-void NetworkSelectionView::NetworkChanged(chromeos::NetworkLibrary* network) {
-  // TODO(nkostylev): Add cellular networks and Ethernet to the list.
-  if (network && network->EnsureLoaded()) {
-    wifi_networks_ = network->wifi_networks();
-  } else {
-    wifi_networks_.clear();
+bool NetworkSelectionView::OnPasswordDialogAccept(const std::string& ssid,
+                                                  const string16& password) {
+  chromeos::NetworkList::NetworkItem* network =
+      networks_.GetNetworkById(chromeos::NetworkList::NETWORK_WIFI,
+                               ASCIIToUTF16(ssid));
+  if (network &&
+      chromeos::NetworkList::NETWORK_WIFI == network->network_type) {
+    chromeos::NetworkLibrary::Get()->ConnectToWifiNetwork(network->wifi_network,
+                                                          password);
+    NotifyOnConnection();
   }
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NetworkLibrary::Observer implementation:
+
+void NetworkSelectionView::NetworkChanged(
+    chromeos::NetworkLibrary* network_lib) {
+  // Save network selection in case it would be available after refresh.
+  chromeos::NetworkList::NetworkType network_type =
+    chromeos::NetworkList::NETWORK_EMPTY;
+  string16 network_id;
+  chromeos::NetworkList::NetworkItem* network = GetSelectedNetwork();
+  if (network) {
+    network_type = network->network_type;
+    network_id = network->label;
+  }
+  networks_.NetworkChanged(network_lib);
   network_combobox_->ModelChanged();
+  SelectNetwork(network_type, network_id);
 }
 
 void NetworkSelectionView::NetworkTraffic(chromeos::NetworkLibrary* cros,
@@ -204,11 +264,36 @@
 ////////////////////////////////////////////////////////////////////////////////
 // NetworkSelectionView, private:
 
-bool NetworkSelectionView::HasWifiNetworks() {
-  return !wifi_networks_.empty();
+chromeos::NetworkList::NetworkItem* NetworkSelectionView::GetSelectedNetwork() {
+  return networks_.GetNetworkAt(network_combobox_->selected_item() - 1);
 }
 
-const chromeos::WifiNetwork& NetworkSelectionView::GetWifiNetworkAt(int index) {
-  return wifi_networks_[index-1];
+void NetworkSelectionView::NotifyOnConnection() {
+  if (observer_) {
+    observer_->OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED);
+  }
 }
 
+void NetworkSelectionView::OpenPasswordDialog(chromeos::WifiNetwork network) {
+  // TODO(nkostylev): Reuse this code in network menu button.
+  chromeos::PasswordDialogView* dialog = new chromeos::PasswordDialogView(
+      this, network.ssid);
+  views::Window* window = views::Window::CreateChromeWindow(
+      GetWindow()->GetNativeWindow(), gfx::Rect(), dialog);
+  gfx::Size size = dialog->GetPreferredSize();
+  gfx::Rect rect = bounds();
+  gfx::Point point = gfx::Point(rect.width() - size.width(), rect.height());
+  ConvertPointToScreen(this, &point);
+  window->SetBounds(gfx::Rect(point, size), GetWindow()->GetNativeWindow());
+  window->Show();
+}
+
+void NetworkSelectionView::SelectNetwork(
+    chromeos::NetworkList::NetworkType type,const string16& id) {
+  int index = networks_.GetNetworkIndexById(type, id);
+  if (index >= 0) {
+    network_combobox_->SetSelectedItem(index + 1);
+  } else {
+    network_combobox_->SetSelectedItem(0);
+  }
+}
diff --git a/chrome/browser/chromeos/login/network_selection_view.h b/chrome/browser/chromeos/login/network_selection_view.h
index 428bf73..050d644 100644
--- a/chrome/browser/chromeos/login/network_selection_view.h
+++ b/chrome/browser/chromeos/login/network_selection_view.h
@@ -9,6 +9,9 @@
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/rounded_rect_painter.h"
 #include "chrome/browser/chromeos/login/wizard_screen.h"
+#include "chrome/browser/chromeos/network_list.h"
+#include "chrome/browser/chromeos/status/password_dialog_view.h"
+#include "views/controls/button/button.h"
 #include "views/controls/combobox/combobox.h"
 #include "views/widget/widget_gtk.h"
 #include "views/window/window_delegate.h"
@@ -19,6 +22,7 @@
 
 namespace views {
 class Label;
+class NativeButton;
 }  // namespace views
 
 // View for the network selection/initial welcome screen.
@@ -26,6 +30,8 @@
                              public views::WindowDelegate,
                              public ComboboxModel,
                              public views::Combobox::Listener,
+                             public views::ButtonListener,
+                             public chromeos::PasswordDialogDelegate,
                              public chromeos::NetworkLibrary::Observer {
  public:
   explicit NetworkSelectionView(chromeos::ScreenObserver* observer);
@@ -51,29 +57,43 @@
                            int prev_index,
                            int new_index);
 
+  // views::ButtonListener implementation:
+  virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+  // PasswordDialogDelegate implementation:
+  virtual bool OnPasswordDialogCancel() { return true; }
+  virtual bool OnPasswordDialogAccept(const std::string& ssid,
+                                      const string16& password);
+
   // NetworkLibrary::Observer implementation:
-  virtual void NetworkChanged(chromeos::NetworkLibrary* obj);
+  virtual void NetworkChanged(chromeos::NetworkLibrary* network_lib);
   virtual void NetworkTraffic(chromeos::NetworkLibrary* cros, int traffic_type);
 
  private:
-  // Returns true if there's at least one Wifi network available in the model.
-  bool HasWifiNetworks();
+  // Returns currently selected network in the combobox.
+   chromeos::NetworkList::NetworkItem* GetSelectedNetwork();
 
-  // Returns WiFi network by index from model.
-  const chromeos::WifiNetwork& GetWifiNetworkAt(int index);
+  // Notifies wizard on successful connection.
+  void NotifyOnConnection();
+
+  // Opens password dialog for the encrypted networks.
+  void OpenPasswordDialog(chromeos::WifiNetwork network);
+
+  // Selects network by type and id.
+  void SelectNetwork(chromeos::NetworkList::NetworkType type,
+                     const string16& id);
 
   // Dialog controls.
   views::Combobox* network_combobox_;
   views::Label* welcome_label_;
   views::Label* select_network_label_;
+  views::NativeButton* offline_button_;
 
   // Notifications receiver.
   chromeos::ScreenObserver* observer_;
 
-  // TODO(nkostylev): Refactor network list which is also represented in
-  // NetworkMenuButton, InternetPageView.
-  // Cached list of WiFi networks (part of combobox model).
-  chromeos::WifiNetworkVector wifi_networks_;
+  // Cached networks.
+  chromeos::NetworkList networks_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkSelectionView);
 };
diff --git a/chrome/browser/chromeos/login/screen_observer.h b/chrome/browser/chromeos/login/screen_observer.h
index 38bd848..eac7a3ec 100644
--- a/chrome/browser/chromeos/login/screen_observer.h
+++ b/chrome/browser/chromeos/login/screen_observer.h
@@ -18,7 +18,9 @@
   // exit code for each way to exit the screen for each screen.
   enum ExitCodes {
     LOGIN_SIGN_IN_SELECTED,
+    LOGIN_BACK,
     NETWORK_CONNECTED,
+    NETWORK_OFFLINE,
     ACCOUNT_CREATED,
   };
 
diff --git a/chrome/browser/chromeos/network_list.cc b/chrome/browser/chromeos/network_list.cc
new file mode 100644
index 0000000..09c1e64
--- /dev/null
+++ b/chrome/browser/chromeos/network_list.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/network_list.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "grit/generated_resources.h"
+
+namespace chromeos {
+
+NetworkList::NetworkList()
+    : ethernet_connected_(false),
+      connected_network_(-1) {
+}
+
+NetworkList::NetworkItem* NetworkList::GetNetworkAt(int index) {
+  return index >= 0 && index < static_cast<int>(networks_.size()) ?
+      &networks_[index] : NULL;
+}
+
+NetworkList::NetworkItem* NetworkList::GetNetworkById(NetworkType type,
+                                                      const string16& id) {
+  return GetNetworkAt(GetNetworkIndexById(type, id));
+}
+
+int NetworkList::GetNetworkIndexById(NetworkType type,
+                                     const string16& id) const {
+  if (NETWORK_EMPTY == type || id.empty()) return -1;
+  std::string network_id = UTF16ToASCII(id);
+  for (size_t i = 0; i < networks_.size(); i++) {
+    if (type == networks_[i].network_type) {
+      switch (type) {
+        case NETWORK_ETHERNET:
+          // Assuming that there's only single Ethernet network.
+          return i;
+
+        case NETWORK_WIFI:
+          if (network_id == networks_[i].wifi_network.ssid)
+            return i;
+          break;
+
+        case NETWORK_CELLULAR:
+          if (network_id == networks_[i].cellular_network.name)
+            return i;
+          break;
+
+        default:
+          break;
+      }
+    }
+  }
+  return -1;
+}
+
+void NetworkList::NetworkChanged(chromeos::NetworkLibrary* network_lib) {
+  networks_.clear();
+  if (!network_lib || !network_lib->EnsureLoaded())
+    return;
+
+  ethernet_connected_ = network_lib->ethernet_connected();
+  if (ethernet_connected_) {
+    string16 label = l10n_util::GetStringUTF16(
+        IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
+    networks_.push_back(NetworkItem(NETWORK_ETHERNET,
+                                    label,
+                                    WifiNetwork(),
+                                    CellularNetwork()));
+  }
+
+  // TODO(nkostylev): Show public WiFi networks first.
+  WifiNetworkVector wifi = network_lib->wifi_networks();
+  for (WifiNetworkVector::const_iterator it = wifi.begin();
+       it != wifi.end(); ++it) {
+    networks_.push_back(NetworkItem(NETWORK_WIFI,
+                                    ASCIIToUTF16(it->ssid),
+                                    *it,
+                                    CellularNetwork()));
+  }
+
+  CellularNetworkVector cellular = network_lib->cellular_networks();
+  for (CellularNetworkVector::const_iterator it = cellular.begin();
+       it != cellular.end(); ++it) {
+    networks_.push_back(NetworkItem(NETWORK_CELLULAR,
+                                    ASCIIToUTF16(it->name),
+                                    WifiNetwork(),
+                                    *it));
+  }
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/network_list.h b/chrome/browser/chromeos/network_list.h
new file mode 100644
index 0000000..11e2738
--- /dev/null
+++ b/chrome/browser/chromeos/network_list.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_NETWORK_LIST_H_
+#define CHROME_BROWSER_CHROMEOS_NETWORK_LIST_H_
+
+#include <vector>
+
+#include "chrome/browser/chromeos/cros/network_library.h"
+
+namespace chromeos {
+
+// Represents list of currently available networks (Ethernet, Cellular, WiFi).
+// TODO(nkostylev): Refactor network list which is also represented in
+// NetworkMenuButton, InternetPageView.
+class NetworkList  {
+ public:
+  enum NetworkType {
+    NETWORK_EMPTY,      // Non-initialized network item.
+    NETWORK_ETHERNET,
+    NETWORK_CELLULAR,
+    NETWORK_WIFI,
+  };
+
+  struct NetworkItem {
+    NetworkItem()
+        : network_type(NETWORK_EMPTY),
+          connected(false) {}
+    NetworkItem(NetworkType network_type,
+                string16 label,
+                WifiNetwork wifi_network,
+                CellularNetwork cellular_network)
+        : network_type(network_type),
+          label(label),
+          wifi_network(wifi_network),
+          cellular_network(cellular_network),
+          connected(false) {}
+
+    NetworkType network_type;
+    string16 label;      // string representation of the network (shown in UI).
+    WifiNetwork wifi_network;
+    CellularNetwork cellular_network;
+    bool connected;
+  };
+
+  NetworkList();
+  virtual ~NetworkList() {}
+
+  // True if network list is empty.
+  bool IsEmpty() const {
+    return networks_.empty();
+  }
+
+  // Returns network by it's type and ssid (Wifi) or id (Cellular).
+  // If network is not available NULL is returned.
+  NetworkList::NetworkItem* GetNetworkById(NetworkType type,
+                                           const string16& id);
+
+  // Returns network index by it's type and ssid (Wifi) or id (Cellular).
+  // If network is not available -1 is returned.
+  int GetNetworkIndexById(NetworkType type, const string16& id) const;
+
+  // Returns number of networks.
+  size_t GetNetworkCount() const {
+    return networks_.size();
+  }
+
+  // Returns network by index.
+  NetworkList::NetworkItem* GetNetworkAt(int index);
+
+  // Callback from NetworkLibrary.
+  void NetworkChanged(chromeos::NetworkLibrary* network_lib);
+
+ private:
+  typedef std::vector<NetworkItem> NetworkItemVector;
+
+  // Cached list of all available networks.
+  NetworkItemVector networks_;
+
+  // True if Ethernet network is connected.
+  bool ethernet_connected_;
+
+  // Index of currently connected network. Ethernet has priority.
+  int connected_network_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkList);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_NETWORK_LIST_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index c5f031d..a309975f 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -333,6 +333,8 @@
         'browser/chromeos/login/wizard_screen.h',
         'browser/chromeos/main_menu.cc',
         'browser/chromeos/main_menu.h',
+        'browser/chromeos/network_list.cc',
+        'browser/chromeos/network_list.h',
         'browser/chromeos/options/internet_page_view.cc',
         'browser/chromeos/options/internet_page_view.h',
         'browser/chromeos/options/settings_page_view.cc',