| Index: chrome/browser/chromeos/status/network_menu.cc
 | 
| diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..30065a6007ec6f89614508f3ee8a9e2ae00b179d
 | 
| --- /dev/null
 | 
| +++ b/chrome/browser/chromeos/status/network_menu.cc
 | 
| @@ -0,0 +1,360 @@
 | 
| +// 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/status/network_menu.h"
 | 
| +
 | 
| +#include "app/l10n_util.h"
 | 
| +#include "app/resource_bundle.h"
 | 
| +#include "base/utf_string_conversions.h"
 | 
| +#include "chrome/browser/chromeos/cros/cros_library.h"
 | 
| +#include "gfx/canvas_skia.h"
 | 
| +#include "gfx/skbitmap_operations.h"
 | 
| +#include "grit/generated_resources.h"
 | 
| +#include "grit/theme_resources.h"
 | 
| +#include "views/window/window.h"
 | 
| +
 | 
| +namespace chromeos {
 | 
| +
 | 
| +////////////////////////////////////////////////////////////////////////////////
 | 
| +// NetworkMenu
 | 
| +
 | 
| +// static
 | 
| +const int NetworkMenu::kNumWifiImages = 9;
 | 
| +
 | 
| +NetworkMenu::NetworkMenu()
 | 
| +    : ALLOW_THIS_IN_INITIALIZER_LIST(network_menu_(this)) {
 | 
| +}
 | 
| +
 | 
| +NetworkMenu::~NetworkMenu() {
 | 
| +}
 | 
| +
 | 
| +////////////////////////////////////////////////////////////////////////////////
 | 
| +// NetworkMenu, menus::MenuModel implementation:
 | 
| +
 | 
| +int NetworkMenu::GetItemCount() const {
 | 
| +  return static_cast<int>(menu_items_.size());
 | 
| +}
 | 
| +
 | 
| +menus::MenuModel::ItemType NetworkMenu::GetTypeAt(int index) const {
 | 
| +  return menu_items_[index].type;
 | 
| +}
 | 
| +
 | 
| +string16 NetworkMenu::GetLabelAt(int index) const {
 | 
| +  return menu_items_[index].label;
 | 
| +}
 | 
| +
 | 
| +const gfx::Font* NetworkMenu::GetLabelFontAt(int index) const {
 | 
| +  return (menu_items_[index].flags & FLAG_ASSOCIATED) ?
 | 
| +      &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) :
 | 
| +      NULL;
 | 
| +}
 | 
| +
 | 
| +bool NetworkMenu::IsItemCheckedAt(int index) const {
 | 
| +  // All menus::MenuModel::TYPE_CHECK menu items are checked.
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) const {
 | 
| +  if (!menu_items_[index].icon.empty()) {
 | 
| +    *icon = menu_items_[index].icon;
 | 
| +    return true;
 | 
| +  }
 | 
| +  return false;
 | 
| +}
 | 
| +
 | 
| +bool NetworkMenu::IsEnabledAt(int index) const {
 | 
| +  return !(menu_items_[index].flags & FLAG_DISABLED);
 | 
| +}
 | 
| +
 | 
| +void NetworkMenu::ActivatedAt(int index) {
 | 
| +  // When we are refreshing the menu, ignore menu item activation.
 | 
| +  if (refreshing_menu_)
 | 
| +    return;
 | 
| +
 | 
| +  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
 | 
| +  int flags = menu_items_[index].flags;
 | 
| +  if (flags & FLAG_OPTIONS) {
 | 
| +    OpenButtonOptions();
 | 
| +  } else if (flags & FLAG_TOGGLE_ETHERNET) {
 | 
| +    cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled());
 | 
| +  } else if (flags & FLAG_TOGGLE_WIFI) {
 | 
| +    cros->EnableWifiNetworkDevice(!cros->wifi_enabled());
 | 
| +  } else if (flags & FLAG_TOGGLE_CELLULAR) {
 | 
| +    cros->EnableCellularNetworkDevice(!cros->cellular_enabled());
 | 
| +  } else if (flags & FLAG_TOGGLE_OFFLINE) {
 | 
| +    cros->EnableOfflineMode(!cros->offline_mode());
 | 
| +  } else if (flags & FLAG_OTHER_NETWORK) {
 | 
| +    NetworkConfigView* view = new NetworkConfigView();
 | 
| +    view->set_browser_mode(IsBrowserMode());
 | 
| +    views::Window* window = views::Window::CreateChromeWindow(GetNativeWindow(),
 | 
| +                                                              gfx::Rect(),
 | 
| +                                                              view);
 | 
| +    window->SetIsAlwaysOnTop(true);
 | 
| +    window->Show();
 | 
| +    view->SetLoginTextfieldFocus();
 | 
| +  } else if (flags & FLAG_ETHERNET) {
 | 
| +    if (cros->ethernet_connected()) {
 | 
| +      NetworkConfigView* view = new NetworkConfigView(cros->ethernet_network());
 | 
| +      view->set_browser_mode(IsBrowserMode());
 | 
| +      views::Window* window = views::Window::CreateChromeWindow(
 | 
| +          GetNativeWindow(), gfx::Rect(), view);
 | 
| +      window->SetIsAlwaysOnTop(true);
 | 
| +      window->Show();
 | 
| +    }
 | 
| +  } else if (flags & FLAG_WIFI) {
 | 
| +    WifiNetwork wifi;
 | 
| +    bool wifi_exists = cros->FindWifiNetworkByPath(
 | 
| +        menu_items_[index].wireless_path, &wifi);
 | 
| +    if (!wifi_exists) {
 | 
| +      // If we are attempting to connect to a network that no longer exists,
 | 
| +      // display a notification.
 | 
| +      // TODO(stevenjb): Show notification.
 | 
| +    } else if (wifi.name() == cros->wifi_name()) {
 | 
| +      if (cros->wifi_connected()) {
 | 
| +        // If we are already connected, open the config dialog.
 | 
| +        NetworkConfigView* view = new NetworkConfigView(wifi, false);
 | 
| +        view->set_browser_mode(IsBrowserMode());
 | 
| +        views::Window* window = views::Window::CreateChromeWindow(
 | 
| +            GetNativeWindow(), gfx::Rect(), view);
 | 
| +        window->SetIsAlwaysOnTop(true);
 | 
| +        window->Show();
 | 
| +      } else {
 | 
| +        // TODO(stevenjb): Connection in progress. Show dialog?
 | 
| +      }
 | 
| +    } else {
 | 
| +      // If wifi network is not encrypted, then directly connect.
 | 
| +      // Otherwise, we open password dialog window.
 | 
| +      if (!wifi.encrypted()) {
 | 
| +        cros->ConnectToWifiNetwork(wifi, std::string(),
 | 
| +                                   std::string(), std::string());
 | 
| +      } else {
 | 
| +        NetworkConfigView* view = new NetworkConfigView(wifi, true);
 | 
| +        view->set_browser_mode(IsBrowserMode());
 | 
| +        views::Window* window = views::Window::CreateChromeWindow(
 | 
| +            GetNativeWindow(), gfx::Rect(), view);
 | 
| +        window->SetIsAlwaysOnTop(true);
 | 
| +        window->Show();
 | 
| +        view->SetLoginTextfieldFocus();
 | 
| +      }
 | 
| +    }
 | 
| +  } else if (flags & FLAG_CELLULAR) {
 | 
| +    CellularNetwork cellular;
 | 
| +    bool cellular_exists = cros->FindCellularNetworkByPath(
 | 
| +        menu_items_[index].wireless_path, &cellular);
 | 
| +
 | 
| +    if (!cellular_exists) {
 | 
| +      // If we are attempting to connect to a network that no longer exists,
 | 
| +      // display a notification.
 | 
| +      // TODO(stevenjb): Show notification.
 | 
| +    } else if (cellular.name() == cros->cellular_name()) {
 | 
| +      // If clicked on a network that we are already connected to or we are
 | 
| +      // currently trying to connect to, then open config dialog.
 | 
| +      if (cros->cellular_connected()) {
 | 
| +        NetworkConfigView* view = new NetworkConfigView(cellular);
 | 
| +        view->set_browser_mode(IsBrowserMode());
 | 
| +        views::Window* window = views::Window::CreateChromeWindow(
 | 
| +            GetNativeWindow(), gfx::Rect(), view);
 | 
| +        window->SetIsAlwaysOnTop(true);
 | 
| +        window->Show();
 | 
| +      } else {
 | 
| +        // TODO(stevenjb): Connection in progress. Show dialog?
 | 
| +      }
 | 
| +    } else {
 | 
| +      cros->ConnectToCellularNetwork(cellular);
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +void NetworkMenu::SetFirstLevelMenuWidth(int width) {
 | 
| +  gtk_widget_set_size_request(network_menu_.GetNativeMenu(), width, -1);
 | 
| +}
 | 
| +
 | 
| +void NetworkMenu::CancelMenu() {
 | 
| +  network_menu_.CancelMenu();
 | 
| +}
 | 
| +
 | 
| +// static
 | 
| +SkBitmap NetworkMenu::IconForNetworkStrength(int strength, bool black) {
 | 
| +  // Compose wifi icon by superimposing various icons.
 | 
| +  // NOTE: Use an array rather than just calculating a resource number to avoid
 | 
| +  // creating implicit ordering dependencies on the resource values.
 | 
| +  static const int kBarsImages[kNumWifiImages] = {
 | 
| +    IDR_STATUSBAR_NETWORK_BARS1,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS2,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS3,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS4,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS5,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS6,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS7,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS8,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS9,
 | 
| +  };
 | 
| +  static const int kBarsBlackImages[kNumWifiImages] = {
 | 
| +    IDR_STATUSBAR_NETWORK_BARS1_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS2_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS3_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS4_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS5_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS6_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS7_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS8_BLACK,
 | 
| +    IDR_STATUSBAR_NETWORK_BARS9_BLACK,
 | 
| +  };
 | 
| +
 | 
| +  int index = static_cast<int>(strength / 100.0 *
 | 
| +      nextafter(static_cast<float>(kNumWifiImages), 0));
 | 
| +  index = std::max(std::min(index, kNumWifiImages - 1), 0);
 | 
| +  return *ResourceBundle::GetSharedInstance().GetBitmapNamed(
 | 
| +      black ? kBarsBlackImages[index] : kBarsImages[index]);
 | 
| +}
 | 
| +
 | 
| +// static
 | 
| +SkBitmap NetworkMenu::IconForDisplay(SkBitmap icon, SkBitmap badge) {
 | 
| +  // Icons are 24x24.
 | 
| +  static const int kIconWidth = 24;
 | 
| +  static const int kIconHeight = 24;
 | 
| +  // Draw the network icon 3 pixels down to center it.
 | 
| +  static const int kIconX = 0;
 | 
| +  static const int kIconY = 3;
 | 
| +  // Draw badge at (14,14).
 | 
| +  static const int kBadgeX = 14;
 | 
| +  static const int kBadgeY = 14;
 | 
| +
 | 
| +  gfx::CanvasSkia canvas(kIconWidth, kIconHeight, false);
 | 
| +  canvas.DrawBitmapInt(icon, kIconX, kIconY);
 | 
| +  if (!badge.empty())
 | 
| +    canvas.DrawBitmapInt(badge, kBadgeX, kBadgeY);
 | 
| +  return canvas.ExtractBitmap();
 | 
| +}
 | 
| +
 | 
| +////////////////////////////////////////////////////////////////////////////////
 | 
| +// NetworkMenu, views::ViewMenuDelegate implementation:
 | 
| +
 | 
| +void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) {
 | 
| +  refreshing_menu_ = true;
 | 
| +  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
 | 
| +  cros->RequestWifiScan();
 | 
| +  cros->UpdateSystemInfo();
 | 
| +  InitMenuItems();
 | 
| +  network_menu_.Rebuild();
 | 
| +  network_menu_.UpdateStates();
 | 
| +  refreshing_menu_ = false;
 | 
| +  network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
 | 
| +}
 | 
| +
 | 
| +void NetworkMenu::InitMenuItems() {
 | 
| +  menu_items_.clear();
 | 
| +  // Populate our MenuItems with the current list of wifi networks.
 | 
| +  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
 | 
| +  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
 | 
| +
 | 
| +  // Ethernet
 | 
| +  string16 label = l10n_util::GetStringUTF16(
 | 
| +                       IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
 | 
| +  SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK);
 | 
| +  SkBitmap badge = cros->ethernet_connecting() || cros->ethernet_connected() ?
 | 
| +      SkBitmap() : *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED);
 | 
| +  int flag = (cros->ethernet_connecting() || cros->ethernet_connected()) ?
 | 
| +      FLAG_ETHERNET | FLAG_ASSOCIATED : FLAG_ETHERNET;
 | 
| +  menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +      IconForDisplay(icon, badge), std::string(), flag));
 | 
| +
 | 
| +  // Wifi
 | 
| +  const WifiNetworkVector& wifi_networks = cros->wifi_networks();
 | 
| +  // Wifi networks ssids.
 | 
| +  for (size_t i = 0; i < wifi_networks.size(); ++i) {
 | 
| +    label = ASCIIToUTF16(wifi_networks[i].name());
 | 
| +    SkBitmap icon = IconForNetworkStrength(wifi_networks[i].strength(), true);
 | 
| +    SkBitmap badge = wifi_networks[i].encrypted() ?
 | 
| +        *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : SkBitmap();
 | 
| +    flag = (wifi_networks[i].name() == cros->wifi_name()) ?
 | 
| +        FLAG_WIFI | FLAG_ASSOCIATED : FLAG_WIFI;
 | 
| +    menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +        IconForDisplay(icon, badge), wifi_networks[i].service_path(), flag));
 | 
| +  }
 | 
| +
 | 
| +  // Cellular
 | 
| +  const CellularNetworkVector& cell_networks = cros->cellular_networks();
 | 
| +  // Cellular networks ssids.
 | 
| +  for (size_t i = 0; i < cell_networks.size(); ++i) {
 | 
| +    label = ASCIIToUTF16(cell_networks[i].name());
 | 
| +    SkBitmap icon = IconForNetworkStrength(cell_networks[i].strength(), true);
 | 
| +    // TODO(chocobo): Check cellular network 3g/edge.
 | 
| +    SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_3G);
 | 
| +//    SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_EDGE);
 | 
| +    flag = (cell_networks[i].name() == cros->cellular_name()) ?
 | 
| +        FLAG_CELLULAR | FLAG_ASSOCIATED : FLAG_CELLULAR;
 | 
| +    menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +        IconForDisplay(icon, badge), cell_networks[i].service_path(), flag));
 | 
| +  }
 | 
| +
 | 
| +  // No networks available message.
 | 
| +  if (wifi_networks.empty() && cell_networks.empty()) {
 | 
| +    label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT,
 | 
| +                l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE));
 | 
| +    menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +        SkBitmap(), std::string(), FLAG_DISABLED));
 | 
| +  }
 | 
| +
 | 
| +  // Other networks
 | 
| +  menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND,
 | 
| +      l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_NETWORKS),
 | 
| +      IconForDisplay(*rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0),
 | 
| +                     SkBitmap()),
 | 
| +      std::string(), FLAG_OTHER_NETWORK));
 | 
| +
 | 
| +  if (cros->wifi_available() || cros->cellular_available()) {
 | 
| +    // Separator.
 | 
| +    menu_items_.push_back(MenuItem());
 | 
| +
 | 
| +    // Turn Wifi Off. (only if wifi available)
 | 
| +    if (cros->wifi_available()) {
 | 
| +      int id = cros->wifi_enabled() ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE :
 | 
| +                                      IDS_STATUSBAR_NETWORK_DEVICE_ENABLE;
 | 
| +      label = l10n_util::GetStringFUTF16(id,
 | 
| +          l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI));
 | 
| +      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +          SkBitmap(), std::string(), FLAG_TOGGLE_WIFI));
 | 
| +    }
 | 
| +
 | 
| +    // Turn Cellular Off. (only if cellular available)
 | 
| +    if (cros->cellular_available()) {
 | 
| +      int id = cros->cellular_enabled() ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE :
 | 
| +                                      IDS_STATUSBAR_NETWORK_DEVICE_ENABLE;
 | 
| +      label = l10n_util::GetStringFUTF16(id,
 | 
| +          l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CELLULAR));
 | 
| +      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +          SkBitmap(), std::string(), FLAG_TOGGLE_CELLULAR));
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  // TODO(chocobo): Uncomment once we figure out how to do offline mode.
 | 
| +  // Offline mode.
 | 
| +//  menu_items_.push_back(MenuItem(cros->offline_mode() ?
 | 
| +//      menus::MenuModel::TYPE_CHECK : menus::MenuModel::TYPE_COMMAND,
 | 
| +//      l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OFFLINE_MODE),
 | 
| +//      SkBitmap(), std::string(), FLAG_TOGGLE_OFFLINE));
 | 
| +
 | 
| +  if (cros->Connected() || ShouldOpenButtonOptions()) {
 | 
| +    // Separator.
 | 
| +    menu_items_.push_back(MenuItem());
 | 
| +
 | 
| +    // IP address
 | 
| +    if (cros->Connected()) {
 | 
| +      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND,
 | 
| +          ASCIIToUTF16(cros->IPAddress()), SkBitmap(),
 | 
| +          std::string(), FLAG_DISABLED));
 | 
| +    }
 | 
| +
 | 
| +    // Network settings.
 | 
| +    if (ShouldOpenButtonOptions()) {
 | 
| +      label =
 | 
| +          l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OPEN_OPTIONS_DIALOG);
 | 
| +      menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label,
 | 
| +          SkBitmap(), std::string(), FLAG_OPTIONS));
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +}  // namespace chromeos
 | 
| 
 |