summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-10 21:03:33 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-10 21:03:33 +0000
commit0fb499a5b8b8d2979e7dafe93e8e6689fdedabd8 (patch)
tree688dadc8de73b7f0eb4d9211a249f537ec366e3d /chrome/browser/chromeos
parent4057c5d217e93a6f05ade5801f45196f3ff738cb (diff)
downloadchromium_src-0fb499a5b8b8d2979e7dafe93e8e6689fdedabd8.zip
chromium_src-0fb499a5b8b8d2979e7dafe93e8e6689fdedabd8.tar.gz
chromium_src-0fb499a5b8b8d2979e7dafe93e8e6689fdedabd8.tar.bz2
Unrevert 31478 Add UI for turning on/off network devices.
BUG=26636 TEST=run skbitmap_operations_unittest Review URL: http://codereview.chromium.org/353028 TBR=chocobo@google.com Review URL: http://codereview.chromium.org/384017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31598 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos')
-rw-r--r--chrome/browser/chromeos/network_library.cc72
-rw-r--r--chrome/browser/chromeos/network_library.h49
-rw-r--r--chrome/browser/chromeos/network_menu_button.cc231
-rw-r--r--chrome/browser/chromeos/network_menu_button.h68
4 files changed, 336 insertions, 84 deletions
diff --git a/chrome/browser/chromeos/network_library.cc b/chrome/browser/chromeos/network_library.cc
index e4599a1..13e216d 100644
--- a/chrome/browser/chromeos/network_library.cc
+++ b/chrome/browser/chromeos/network_library.cc
@@ -29,7 +29,7 @@ const int NetworkLibrary::kNetworkTrafficeTimerSecs = 1;
NetworkLibrary::NetworkLibrary()
: traffic_type_(0),
- ethernet_connected_(false) {
+ network_devices_(0) {
if (CrosLibrary::loaded()) {
Init();
}
@@ -112,36 +112,44 @@ void NetworkLibrary::ConnectToWifiNetwork(WifiNetwork network,
}
}
+void NetworkLibrary::EnableEthernetNetworkDevice(bool enable) {
+ EnableNetworkDevice(chromeos::TYPE_ETHERNET, enable);
+}
+
+void NetworkLibrary::EnableWifiNetworkDevice(bool enable) {
+ EnableNetworkDevice(chromeos::TYPE_WIFI, enable);
+}
+
// static
void NetworkLibrary::NetworkStatusChangedHandler(void* object,
const chromeos::ServiceStatus& service_status) {
NetworkLibrary* network = static_cast<NetworkLibrary*>(object);
WifiNetworkVector networks;
- bool ethernet_connected;
- ParseNetworks(service_status, &networks, &ethernet_connected);
- network->UpdateNetworkStatus(networks, ethernet_connected);
+ EthernetNetwork ethernet;
+ ParseNetworks(service_status, &networks, &ethernet);
+ network->UpdateNetworkStatus(networks, ethernet);
}
// static
void NetworkLibrary::ParseNetworks(
const chromeos::ServiceStatus& service_status, WifiNetworkVector* networks,
- bool* ethernet_connected) {
- *ethernet_connected = false;
+ EthernetNetwork* ethernet) {
+ DLOG(INFO) << "ParseNetworks:";
for (int i = 0; i < service_status.size; i++) {
const chromeos::ServiceInfo& service = service_status.services[i];
- DLOG(INFO) << "Parse " << service.ssid <<
+ DLOG(INFO) << " " << service.ssid <<
" typ=" << service.type <<
" sta=" << service.state <<
" pas=" << service.needs_passphrase <<
" enc=" << service.encryption <<
" sig=" << service.signal_strength;
+ bool connecting = service.state == chromeos::STATE_ASSOCIATION ||
+ service.state == chromeos::STATE_CONFIGURATION;
+ bool connected = service.state == chromeos::STATE_READY;
if (service.type == chromeos::TYPE_ETHERNET) {
- // Get the ethernet status.
- *ethernet_connected = service.state == chromeos::STATE_READY;
+ ethernet->connecting = connecting;
+ ethernet->connected = connected;
} else if (service.type == chromeos::TYPE_WIFI) {
- bool connecting = service.state == chromeos::STATE_ASSOCIATION ||
- service.state == chromeos::STATE_CONFIGURATION;
- bool connected = service.state == chromeos::STATE_READY;
networks->push_back(WifiNetwork(service.ssid,
service.needs_passphrase,
service.encryption,
@@ -159,30 +167,56 @@ void NetworkLibrary::Init() {
if (service_status) {
LOG(INFO) << "Getting initial CrOS network info.";
WifiNetworkVector networks;
- bool ethernet_connected;
- ParseNetworks(*service_status, &networks, &ethernet_connected);
- UpdateNetworkStatus(networks, ethernet_connected);
+ EthernetNetwork ethernet;
+ ParseNetworks(*service_status, &networks, &ethernet);
+ UpdateNetworkStatus(networks, ethernet);
chromeos::FreeServiceStatus(service_status);
}
LOG(INFO) << "Registering for network status updates.";
// Now, register to receive updates on network status.
network_status_connection_ = chromeos::MonitorNetworkStatus(
&NetworkStatusChangedHandler, this);
+ // Get the enabled network devices.
+ network_devices_ = chromeos::GetEnabledNetworkDevices();
+}
+
+void NetworkLibrary::EnableNetworkDevice(chromeos::ConnectionType device,
+ bool enable) {
+ if (!CrosLibrary::loaded())
+ return;
+
+ // If network device is already enabled/disabled, then don't do anything.
+ if (enable && (network_devices_ & device)) {
+ LOG(INFO) << "Trying to enable a network device that's already enabled: "
+ << device;
+ return;
+ }
+ if (!enable && !(network_devices_ & device)) {
+ LOG(INFO) << "Trying to disable a network device that's already disabled: "
+ << device;
+ return;
+ }
+
+ if (chromeos::EnableNetworkDevice(device, enable)) {
+ if (enable)
+ network_devices_ |= device;
+ else
+ network_devices_ &= ~device;
+ }
}
void NetworkLibrary::UpdateNetworkStatus(
- const WifiNetworkVector& networks, bool ethernet_connected) {
+ const WifiNetworkVector& networks, const EthernetNetwork& ethernet) {
// Make sure we run on UI thread.
if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
ChromeThread::PostTask(
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(this,
- &NetworkLibrary::UpdateNetworkStatus, networks,
- ethernet_connected));
+ &NetworkLibrary::UpdateNetworkStatus, networks, ethernet));
return;
}
- ethernet_connected_ = ethernet_connected;
+ ethernet_ = ethernet;
wifi_networks_ = networks;
// Sort the list of wifi networks by ssid.
std::sort(wifi_networks_.begin(), wifi_networks_.end());
diff --git a/chrome/browser/chromeos/network_library.h b/chrome/browser/chromeos/network_library.h
index 8c67332..baee22b 100644
--- a/chrome/browser/chromeos/network_library.h
+++ b/chrome/browser/chromeos/network_library.h
@@ -18,14 +18,25 @@
namespace chromeos {
+struct EthernetNetwork {
+ EthernetNetwork()
+ : connecting(false),
+ connected(false) {}
+ EthernetNetwork(bool connecting, bool connected)
+ : connecting(connecting),
+ connected(connected) {}
+
+ bool connecting;
+ bool connected;
+};
+
struct WifiNetwork {
WifiNetwork()
: encrypted(false),
encryption(chromeos::NONE),
strength(0),
connecting(false),
- connected(false),
- destroyed(false) {}
+ connected(false) {}
WifiNetwork(const std::string& ssid, bool encrypted,
chromeos::EncryptionType encryption, int strength,
bool connecting, bool connected)
@@ -34,8 +45,7 @@ struct WifiNetwork {
encryption(encryption),
strength(strength),
connecting(connecting),
- connected(connected),
- destroyed(false) {}
+ connected(connected) {}
// WifiNetworks are sorted by ssids.
bool operator< (const WifiNetwork& other) const {
@@ -48,7 +58,6 @@ struct WifiNetwork {
int strength;
bool connecting;
bool connected;
- bool destroyed;
};
typedef std::vector<WifiNetwork> WifiNetworkVector;
@@ -90,9 +99,11 @@ class NetworkLibrary : public URLRequestJobTracker::JobObserver {
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- bool ethernet_connected() const { return ethernet_connected_; }
+ bool ethernet_connecting() const { return ethernet_.connecting; }
+ bool ethernet_connected() const { return ethernet_.connected; }
const std::string& wifi_ssid() const { return wifi_.ssid; }
bool wifi_connecting() const { return wifi_.connecting; }
+ bool wifi_connected() const { return wifi_.connected; }
int wifi_strength() const { return wifi_.strength; }
// Returns the current list of wifi networks.
@@ -101,6 +112,15 @@ class NetworkLibrary : public URLRequestJobTracker::JobObserver {
// Connect to the specified wireless network with password.
void ConnectToWifiNetwork(WifiNetwork network, const string16& password);
+ bool ethernet_enabled() const { return network_devices_ & TYPE_ETHERNET; }
+ bool wifi_enabled() const { return network_devices_ & TYPE_WIFI; }
+
+ // Enables/disables the ethernet network device.
+ void EnableEthernetNetworkDevice(bool enable);
+
+ // Enables/disables the wifi network device.
+ void EnableWifiNetworkDevice(bool enable);
+
private:
friend struct DefaultSingletonTraits<NetworkLibrary>;
@@ -113,19 +133,22 @@ class NetworkLibrary : public URLRequestJobTracker::JobObserver {
const chromeos::ServiceStatus& service_status);
// This parses ServiceStatus and creates a WifiNetworkVector of wifi networks.
- // It also sets ethernet_connected depending on if we have ethernet or not.
+ // It also sets the ethernet connecting/connected status.
static void ParseNetworks(const chromeos::ServiceStatus& service_status,
WifiNetworkVector* networks,
- bool* ethernet_connected);
+ EthernetNetwork* ethernet);
// This methods loads the initial list of networks on startup and starts the
// monitoring of network changes.
void Init();
+ // Enables/disables the specified network device.
+ void EnableNetworkDevice(chromeos::ConnectionType device, bool enable);
+
// Update the network with the a list of wifi networks and ethernet status.
// This will notify all the Observers.
void UpdateNetworkStatus(const WifiNetworkVector& networks,
- bool ethernet_connected);
+ const EthernetNetwork& ethernet);
// Checks network traffic to see if there is any uploading.
// If there is download traffic, then true is passed in for download.
@@ -159,8 +182,8 @@ class NetworkLibrary : public URLRequestJobTracker::JobObserver {
// The network status connection for monitoring network status changes.
chromeos::NetworkStatusConnection network_status_connection_;
- // Whether or not we are connected to the ethernet line.
- bool ethernet_connected_;
+ // The ethernet network.
+ EthernetNetwork ethernet_;
// The list of available wifi networks.
WifiNetworkVector wifi_networks_;
@@ -168,6 +191,10 @@ class NetworkLibrary : public URLRequestJobTracker::JobObserver {
// The current connected (or connecting) wifi network.
WifiNetwork wifi_;
+ // The current enabled network devices. This is a bitwise flag of
+ // ConnectionTypes.
+ int network_devices_;
+
DISALLOW_COPY_AND_ASSIGN(NetworkLibrary);
};
diff --git a/chrome/browser/chromeos/network_menu_button.cc b/chrome/browser/chromeos/network_menu_button.cc
index 75174d9..2a197d8 100644
--- a/chrome/browser/chromeos/network_menu_button.cc
+++ b/chrome/browser/chromeos/network_menu_button.cc
@@ -7,6 +7,7 @@
#include <limits>
#include "app/gfx/canvas.h"
+#include "app/gfx/skbitmap_operations.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/string_util.h"
@@ -25,6 +26,9 @@ const int NetworkMenuButton::kNumWifiImages = 3;
const int NetworkMenuButton::kMinOpacity = 50;
const int NetworkMenuButton::kMaxOpacity = 256;
const int NetworkMenuButton::kThrobDuration = 1000;
+SkBitmap* NetworkMenuButton::menu_wifi_icons_ = NULL;
+SkBitmap* NetworkMenuButton::menu_wired_icon_ = NULL;
+SkBitmap* NetworkMenuButton::menu_disconnected_icon_ = NULL;
NetworkMenuButton::NetworkMenuButton(gfx::NativeWindow browser_window)
: StatusAreaButton(this),
@@ -33,6 +37,27 @@ NetworkMenuButton::NetworkMenuButton(gfx::NativeWindow browser_window)
ALLOW_THIS_IN_INITIALIZER_LIST(animation_connecting_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(animation_downloading_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(animation_uploading_(this)) {
+ // Initialize the static menu icons.
+ static bool initialized = false;
+ if (!initialized) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ menu_wired_icon_ = new SkBitmap(SkBitmapOperations::CreateInvertedBitmap(
+ *rb.GetBitmapNamed(IDR_STATUSBAR_WIRED)));
+ menu_disconnected_icon_ = new SkBitmap(
+ SkBitmapOperations::CreateInvertedBitmap(
+ *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED)));
+ menu_wifi_icons_ = new SkBitmap[kNumWifiImages + 1];
+ SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_DOT);
+ menu_wifi_icons_[0] = SkBitmapOperations::CreateInvertedBitmap(icon);
+ for (int i = 0; i < kNumWifiImages; i++) {
+ icon = SkBitmapOperations::CreateSuperimposedBitmap(icon,
+ *rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_UP1 + i));
+ icon = SkBitmapOperations::CreateSuperimposedBitmap(icon,
+ *rb.GetBitmapNamed(IDR_STATUSBAR_WIFI_DOWN1 + i));
+ menu_wifi_icons_[i + 1] = SkBitmapOperations::CreateInvertedBitmap(icon);
+ }
+ initialized = true;
+ }
animation_connecting_.SetThrobDuration(kThrobDuration);
animation_connecting_.SetTweenType(SlideAnimation::NONE);
animation_downloading_.SetThrobDuration(kThrobDuration);
@@ -51,30 +76,32 @@ NetworkMenuButton::~NetworkMenuButton() {
// NetworkMenuButton, views::Menu2Model implementation:
int NetworkMenuButton::GetItemCount() const {
- // The menu contains the available wifi networks. If there are none, then it
- // only has one item with a message that no networks are available.
- return wifi_networks_.empty() ? 1 : static_cast<int>(wifi_networks_.size());
+ return static_cast<int>(menu_items_.size());
}
views::Menu2Model::ItemType NetworkMenuButton::GetTypeAt(int index) const {
- return wifi_networks_.empty() ? views::Menu2Model::TYPE_COMMAND :
- views::Menu2Model::TYPE_CHECK;
+ return menu_items_[index].type;
}
string16 NetworkMenuButton::GetLabelAt(int index) const {
- return wifi_networks_.empty() ?
- l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE) :
- ASCIIToUTF16(wifi_networks_[index].ssid);
+ return menu_items_[index].label;
}
bool NetworkMenuButton::IsItemCheckedAt(int index) const {
- // WifiNetwork that we are connected to (or connecting to) is checked.
- return wifi_networks_.empty() ? false :
- wifi_networks_[index].ssid == NetworkLibrary::Get()->wifi_ssid();
+ // All views::Menu2Model::TYPE_CHECK menu items are checked.
+ return true;
+}
+
+bool NetworkMenuButton::GetIconAt(int index, SkBitmap* icon) const {
+ if (!menu_items_[index].icon.empty()) {
+ *icon = menu_items_[index].icon;
+ return true;
+ }
+ return false;
}
bool NetworkMenuButton::IsEnabledAt(int index) const {
- return !wifi_networks_.empty();
+ return !(menu_items_[index].flags & FLAG_DISABLED);
}
void NetworkMenuButton::ActivatedAt(int index) {
@@ -84,29 +111,35 @@ void NetworkMenuButton::ActivatedAt(int index) {
NetworkLibrary* cros = NetworkLibrary::Get();
- // If clicked on a network that we are already connected to or we are
- // currently trying to connect to, then do nothing.
- if (wifi_networks_[index].ssid == cros->wifi_ssid())
- return;
+ if (menu_items_[index].flags & FLAG_TOGGLE_ETHERNET) {
+ cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled());
+ } else if (menu_items_[index].flags & FLAG_TOGGLE_WIFI) {
+ cros->EnableWifiNetworkDevice(!cros->wifi_enabled());
+ } else {
+ activated_wifi_network_ = menu_items_[index].wifi_network;
- activated_wifi_network_ = wifi_networks_[index];
+ // If clicked on a network that we are already connected to or we are
+ // currently trying to connect to, then do nothing.
+ if (activated_wifi_network_.ssid == cros->wifi_ssid())
+ return;
- // If wifi network is not encrypted, then directly connect.
- // Otherwise, we open password dialog window.
- if (!wifi_networks_[index].encrypted) {
- cros->ConnectToWifiNetwork(wifi_networks_[index], string16());
- } else {
- PasswordDialogView* dialog = new PasswordDialogView(this,
- wifi_networks_[index].ssid);
- views::Window* window = views::Window::CreateChromeWindow(
- browser_window_, gfx::Rect(), dialog);
- // Draw the password dialog right below this button and right aligned.
- 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), browser_window_);
- window->Show();
+ // If wifi network is not encrypted, then directly connect.
+ // Otherwise, we open password dialog window.
+ if (!activated_wifi_network_.encrypted) {
+ cros->ConnectToWifiNetwork(activated_wifi_network_, string16());
+ } else {
+ PasswordDialogView* dialog = new PasswordDialogView(this,
+ activated_wifi_network_.ssid);
+ views::Window* window = views::Window::CreateChromeWindow(browser_window_,
+ gfx::Rect(), dialog);
+ // Draw the password dialog right below this button and right aligned.
+ 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), browser_window_);
+ window->Show();
+ }
}
}
@@ -146,12 +179,13 @@ void NetworkMenuButton::DrawIcon(gfx::Canvas* canvas) {
// If wifi, we draw the wifi signal bars.
NetworkLibrary* cros = NetworkLibrary::Get();
if (cros->wifi_connecting() ||
- (!cros->ethernet_connected() && !cros->wifi_ssid().empty())) {
+ (!cros->ethernet_connected() && cros->wifi_connected())) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
// We want a value between 0-1.
// 0 reperesents no signal and 1 represents full signal strength.
double value = cros->wifi_connecting() ?
- animation_connecting_.GetCurrentValue() : cros->wifi_strength() / 100.0;
+ animation_connecting_.GetCurrentValue() :
+ cros->wifi_strength() / 100.0;
if (value < 0)
value = 0;
else if (value > 1)
@@ -223,18 +257,6 @@ void NetworkMenuButton::DrawIcon(gfx::Canvas* canvas) {
}
////////////////////////////////////////////////////////////////////////////////
-// NetworkMenuButton, views::ViewMenuDelegate implementation:
-
-void NetworkMenuButton::RunMenu(views::View* source, const gfx::Point& pt) {
- wifi_networks_ = NetworkLibrary::Get()->wifi_networks();
- refreshing_menu_ = true;
- network_menu_.Rebuild();
- network_menu_.UpdateStates();
- refreshing_menu_ = false;
- network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
-}
-
-////////////////////////////////////////////////////////////////////////////////
// NetworkMenuButton, NetworkLibrary::Observer implementation:
void NetworkMenuButton::NetworkChanged(NetworkLibrary* cros) {
@@ -259,7 +281,7 @@ void NetworkMenuButton::NetworkChanged(NetworkLibrary* cros) {
// Always show the higher priority connection first. Ethernet then wifi.
if (cros->ethernet_connected()) {
id = IDR_STATUSBAR_WIRED;
- } else if (!cros->wifi_ssid().empty()) {
+ } else if (cros->wifi_connected()) {
id = IDR_STATUSBAR_WIFI_DOT;
}
}
@@ -270,7 +292,7 @@ void NetworkMenuButton::NetworkChanged(NetworkLibrary* cros) {
}
void NetworkMenuButton::NetworkTraffic(NetworkLibrary* cros, int traffic_type) {
- if (!cros->ethernet_connected() && !cros->wifi_ssid().empty() &&
+ if (!cros->ethernet_connected() && cros->wifi_connected() &&
!cros->wifi_connecting()) {
// For downloading/uploading animation, we want to force at least one cycle
// so that it looks smooth. And if we keep downloading/uploading, we will
@@ -282,4 +304,115 @@ void NetworkMenuButton::NetworkTraffic(NetworkLibrary* cros, int traffic_type) {
}
}
+// static
+SkBitmap NetworkMenuButton::IconForWifiStrength(int strength) {
+ // Compose wifi icon by superimposing various icons.
+ int index = static_cast<int>(strength / 100.0 *
+ nextafter(static_cast<float>(kNumWifiImages + 1), 0));
+ if (index < 0)
+ index = 0;
+ if (index > kNumWifiImages)
+ index = kNumWifiImages;
+ return menu_wifi_icons_[index];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NetworkMenuButton, views::ViewMenuDelegate implementation:
+
+void NetworkMenuButton::RunMenu(views::View* source, const gfx::Point& pt) {
+ refreshing_menu_ = true;
+ InitMenuItems();
+ network_menu_.Rebuild();
+ network_menu_.UpdateStates();
+ refreshing_menu_ = false;
+ network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
+}
+
+void NetworkMenuButton::InitMenuItems() {
+ menu_items_.clear();
+ // Populate our MenuItems with the current list of wifi networks.
+ NetworkLibrary* cros = NetworkLibrary::Get();
+ const WifiNetworkVector& networks = cros->wifi_networks();
+
+ // Wifi: Status.
+ int status = IDS_STATUSBAR_NETWORK_DEVICE_DISABLED;
+ if (cros->wifi_connecting())
+ status = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
+ else if (cros->wifi_connected())
+ status = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
+ else if (cros->wifi_enabled())
+ status = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
+ string16 label =
+ l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_DEVICE_STATUS,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI),
+ l10n_util::GetStringUTF16(status));
+ SkBitmap icon = cros->wifi_connected() ?
+ IconForWifiStrength(cros->wifi_strength()) :
+ *menu_disconnected_icon_;
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+ icon, WifiNetwork(), FLAG_DISABLED));
+
+ // Turn Wifi Off.
+ label = cros->wifi_enabled() ?
+ l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_DEVICE_DISABLE,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI)) :
+ l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ENABLE,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI));
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+ SkBitmap(), WifiNetwork(), FLAG_TOGGLE_WIFI));
+
+ // Wifi networks ssids.
+ if (networks.empty()) {
+ // No networks available message.
+ label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE));
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+ SkBitmap(), WifiNetwork(), FLAG_DISABLED));
+ } else {
+ for (size_t i = 0; i < networks.size(); ++i) {
+ label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT,
+ ASCIIToUTF16(networks[i].ssid));
+ if (networks[i].ssid == cros->wifi_ssid()) {
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_CHECK, label,
+ SkBitmap(), networks[i], 0));
+ } else {
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+ SkBitmap(), networks[i], 0));
+ // TODO(chocobo): Once we have better icons and more reliable strength
+ // data, show icons for wifi ssids.
+// menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+// IconForWifiStrength(networks[i].strength), networks[i], 0));
+ }
+ }
+ }
+
+ // Separator.
+ menu_items_.push_back(MenuItem());
+
+ // Ethernet: Status.
+ status = IDS_STATUSBAR_NETWORK_DEVICE_DISABLED;
+ if (cros->ethernet_connecting())
+ status = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
+ else if (cros->ethernet_connected())
+ status = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
+ else if (cros->ethernet_enabled())
+ status = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
+ label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_DEVICE_STATUS,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET),
+ l10n_util::GetStringUTF16(status));
+ icon = cros->ethernet_connected() ? *menu_wired_icon_ :
+ *menu_disconnected_icon_;
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+ icon, WifiNetwork(), FLAG_DISABLED));
+
+ // Turn Ethernet Off.
+ label = cros->ethernet_enabled() ?
+ l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_DEVICE_DISABLE,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET)) :
+ l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ENABLE,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET));
+ menu_items_.push_back(MenuItem(views::Menu2Model::TYPE_COMMAND, label,
+ SkBitmap(), WifiNetwork(), FLAG_TOGGLE_ETHERNET));
+}
+
} // namespace chromeos
diff --git a/chrome/browser/chromeos/network_menu_button.h b/chrome/browser/chromeos/network_menu_button.h
index d27c241..8325d5c 100644
--- a/chrome/browser/chromeos/network_menu_button.h
+++ b/chrome/browser/chromeos/network_menu_button.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_CHROMEOS_NETWORK_MENU_BUTTON_H_
#include <string>
+#include <vector>
#include "app/throb_animation.h"
#include "base/timer.h"
@@ -28,6 +29,23 @@ namespace chromeos {
// This class will handle getting the wifi networks and populating the menu.
// It will also handle the status icon changing and connecting to another
// wifi network.
+//
+// The network menu looks like this:
+//
+// <icon> Wifi: <status> (disabled)
+// Turn Wifi <action>
+// <icon> Wifi Network A
+// <check> Wifi Network B
+// <icon> Wifi Network C
+// --------------------------------
+// <icon> Ethernet: <status> (disabled)
+// Turn Ethernet <action>
+//
+// <icon> will show the current state of the network device and the strength of
+// the wifi networks.
+// <check> will be a check mark icon for the currently connected wifi.
+// <status> will be one of: Connected, Connecting, Disconnected, or Disabled.
+// <action> will be either On or Off depending on the current state.
class NetworkMenuButton : public StatusAreaButton,
public views::ViewMenuDelegate,
public views::Menu2Model,
@@ -38,7 +56,7 @@ class NetworkMenuButton : public StatusAreaButton,
virtual ~NetworkMenuButton();
// views::Menu2Model implementation.
- virtual bool HasIcons() const { return false; }
+ virtual bool HasIcons() const { return true; }
virtual int GetItemCount() const;
virtual views::Menu2Model::ItemType GetTypeAt(int index) const;
virtual int GetCommandIdAt(int index) const { return index; }
@@ -48,9 +66,9 @@ class NetworkMenuButton : public StatusAreaButton,
views::Accelerator* accelerator) const { return false; }
virtual bool IsItemCheckedAt(int index) const;
virtual int GetGroupIdAt(int index) const { return 0; }
- virtual bool GetIconAt(int index, SkBitmap* icon) const { return false; }
+ virtual bool GetIconAt(int index, SkBitmap* icon) const;
virtual bool IsEnabledAt(int index) const;
- virtual Menu2Model* GetSubmenuModelAt(int index) const { return NULL; }
+ virtual views::Menu2Model* GetSubmenuModelAt(int index) const { return NULL; }
virtual void HighlightChangedTo(int index) {}
virtual void ActivatedAt(int index);
virtual void MenuWillShow() {}
@@ -72,9 +90,40 @@ class NetworkMenuButton : public StatusAreaButton,
virtual void DrawIcon(gfx::Canvas* canvas);
private:
+ enum MenuItemFlags {
+ FLAG_DISABLED = 0x0001,
+ FLAG_TOGGLE_ETHERNET = 0x0010,
+ FLAG_TOGGLE_WIFI = 0x0100,
+ };
+
+ struct MenuItem {
+ MenuItem()
+ : type(views::Menu2Model::TYPE_SEPARATOR),
+ flags(0) {}
+ MenuItem(views::Menu2Model::ItemType type, string16 label, SkBitmap icon,
+ WifiNetwork wifi_network, int flags)
+ : type(type),
+ label(label),
+ icon(icon),
+ wifi_network(wifi_network),
+ flags(flags) {}
+
+ views::Menu2Model::ItemType type;
+ string16 label;
+ SkBitmap icon;
+ WifiNetwork wifi_network;
+ int flags;
+ };
+ typedef std::vector<MenuItem> MenuItemVector;
+
+ static SkBitmap IconForWifiStrength(int strength);
+
// views::ViewMenuDelegate implementation.
virtual void RunMenu(views::View* source, const gfx::Point& pt);
+ // Called by RunMenu to initialize our list of menu items.
+ void InitMenuItems();
+
// Set to true if we are currently refreshing the menu.
bool refreshing_menu_;
@@ -87,8 +136,17 @@ class NetworkMenuButton : public StatusAreaButton,
// The maximum opacity of the wifi bars.
static const int kMaxOpacity;
- // A list of wifi networks.
- WifiNetworkVector wifi_networks_;
+ // The wifi icons used in menu. These are built on initialization.
+ static SkBitmap* menu_wifi_icons_;
+
+ // The ethernet icon used in menu,
+ static SkBitmap* menu_wired_icon_;
+
+ // The disconnected icon used in menu,
+ static SkBitmap* menu_disconnected_icon_;
+
+ // Our menu items.
+ MenuItemVector menu_items_;
// The activated wifi network.
WifiNetwork activated_wifi_network_;