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 |