OLD | NEW |
(Empty) | |
| 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/utf_string_conversions.h" |
| 10 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 11 #include "gfx/canvas_skia.h" |
| 12 #include "gfx/skbitmap_operations.h" |
| 13 #include "grit/generated_resources.h" |
| 14 #include "grit/theme_resources.h" |
| 15 #include "views/window/window.h" |
| 16 |
| 17 namespace chromeos { |
| 18 |
| 19 //////////////////////////////////////////////////////////////////////////////// |
| 20 // NetworkMenu |
| 21 |
| 22 // static |
| 23 const int NetworkMenu::kNumWifiImages = 9; |
| 24 |
| 25 NetworkMenu::NetworkMenu() |
| 26 : ALLOW_THIS_IN_INITIALIZER_LIST(network_menu_(this)) { |
| 27 } |
| 28 |
| 29 NetworkMenu::~NetworkMenu() { |
| 30 } |
| 31 |
| 32 //////////////////////////////////////////////////////////////////////////////// |
| 33 // NetworkMenu, menus::MenuModel implementation: |
| 34 |
| 35 int NetworkMenu::GetItemCount() const { |
| 36 return static_cast<int>(menu_items_.size()); |
| 37 } |
| 38 |
| 39 menus::MenuModel::ItemType NetworkMenu::GetTypeAt(int index) const { |
| 40 return menu_items_[index].type; |
| 41 } |
| 42 |
| 43 string16 NetworkMenu::GetLabelAt(int index) const { |
| 44 return menu_items_[index].label; |
| 45 } |
| 46 |
| 47 const gfx::Font* NetworkMenu::GetLabelFontAt(int index) const { |
| 48 return (menu_items_[index].flags & FLAG_ASSOCIATED) ? |
| 49 &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) : |
| 50 NULL; |
| 51 } |
| 52 |
| 53 bool NetworkMenu::IsItemCheckedAt(int index) const { |
| 54 // All menus::MenuModel::TYPE_CHECK menu items are checked. |
| 55 return true; |
| 56 } |
| 57 |
| 58 bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) const { |
| 59 if (!menu_items_[index].icon.empty()) { |
| 60 *icon = menu_items_[index].icon; |
| 61 return true; |
| 62 } |
| 63 return false; |
| 64 } |
| 65 |
| 66 bool NetworkMenu::IsEnabledAt(int index) const { |
| 67 return !(menu_items_[index].flags & FLAG_DISABLED); |
| 68 } |
| 69 |
| 70 void NetworkMenu::ActivatedAt(int index) { |
| 71 // When we are refreshing the menu, ignore menu item activation. |
| 72 if (refreshing_menu_) |
| 73 return; |
| 74 |
| 75 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
| 76 int flags = menu_items_[index].flags; |
| 77 if (flags & FLAG_OPTIONS) { |
| 78 OpenButtonOptions(); |
| 79 } else if (flags & FLAG_TOGGLE_ETHERNET) { |
| 80 cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled()); |
| 81 } else if (flags & FLAG_TOGGLE_WIFI) { |
| 82 cros->EnableWifiNetworkDevice(!cros->wifi_enabled()); |
| 83 } else if (flags & FLAG_TOGGLE_CELLULAR) { |
| 84 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); |
| 85 } else if (flags & FLAG_TOGGLE_OFFLINE) { |
| 86 cros->EnableOfflineMode(!cros->offline_mode()); |
| 87 } else if (flags & FLAG_OTHER_NETWORK) { |
| 88 NetworkConfigView* view = new NetworkConfigView(); |
| 89 view->set_browser_mode(IsBrowserMode()); |
| 90 views::Window* window = views::Window::CreateChromeWindow(GetNativeWindow(), |
| 91 gfx::Rect(), |
| 92 view); |
| 93 window->SetIsAlwaysOnTop(true); |
| 94 window->Show(); |
| 95 view->SetLoginTextfieldFocus(); |
| 96 } else if (flags & FLAG_ETHERNET) { |
| 97 if (cros->ethernet_connected()) { |
| 98 NetworkConfigView* view = new NetworkConfigView(cros->ethernet_network()); |
| 99 view->set_browser_mode(IsBrowserMode()); |
| 100 views::Window* window = views::Window::CreateChromeWindow( |
| 101 GetNativeWindow(), gfx::Rect(), view); |
| 102 window->SetIsAlwaysOnTop(true); |
| 103 window->Show(); |
| 104 } |
| 105 } else if (flags & FLAG_WIFI) { |
| 106 WifiNetwork wifi; |
| 107 bool wifi_exists = cros->FindWifiNetworkByPath( |
| 108 menu_items_[index].wireless_path, &wifi); |
| 109 if (!wifi_exists) { |
| 110 // If we are attempting to connect to a network that no longer exists, |
| 111 // display a notification. |
| 112 // TODO(stevenjb): Show notification. |
| 113 } else if (wifi.name() == cros->wifi_name()) { |
| 114 if (cros->wifi_connected()) { |
| 115 // If we are already connected, open the config dialog. |
| 116 NetworkConfigView* view = new NetworkConfigView(wifi, false); |
| 117 view->set_browser_mode(IsBrowserMode()); |
| 118 views::Window* window = views::Window::CreateChromeWindow( |
| 119 GetNativeWindow(), gfx::Rect(), view); |
| 120 window->SetIsAlwaysOnTop(true); |
| 121 window->Show(); |
| 122 } else { |
| 123 // TODO(stevenjb): Connection in progress. Show dialog? |
| 124 } |
| 125 } else { |
| 126 // If wifi network is not encrypted, then directly connect. |
| 127 // Otherwise, we open password dialog window. |
| 128 if (!wifi.encrypted()) { |
| 129 cros->ConnectToWifiNetwork(wifi, std::string(), |
| 130 std::string(), std::string()); |
| 131 } else { |
| 132 NetworkConfigView* view = new NetworkConfigView(wifi, true); |
| 133 view->set_browser_mode(IsBrowserMode()); |
| 134 views::Window* window = views::Window::CreateChromeWindow( |
| 135 GetNativeWindow(), gfx::Rect(), view); |
| 136 window->SetIsAlwaysOnTop(true); |
| 137 window->Show(); |
| 138 view->SetLoginTextfieldFocus(); |
| 139 } |
| 140 } |
| 141 } else if (flags & FLAG_CELLULAR) { |
| 142 CellularNetwork cellular; |
| 143 bool cellular_exists = cros->FindCellularNetworkByPath( |
| 144 menu_items_[index].wireless_path, &cellular); |
| 145 |
| 146 if (!cellular_exists) { |
| 147 // If we are attempting to connect to a network that no longer exists, |
| 148 // display a notification. |
| 149 // TODO(stevenjb): Show notification. |
| 150 } else if (cellular.name() == cros->cellular_name()) { |
| 151 // If clicked on a network that we are already connected to or we are |
| 152 // currently trying to connect to, then open config dialog. |
| 153 if (cros->cellular_connected()) { |
| 154 NetworkConfigView* view = new NetworkConfigView(cellular); |
| 155 view->set_browser_mode(IsBrowserMode()); |
| 156 views::Window* window = views::Window::CreateChromeWindow( |
| 157 GetNativeWindow(), gfx::Rect(), view); |
| 158 window->SetIsAlwaysOnTop(true); |
| 159 window->Show(); |
| 160 } else { |
| 161 // TODO(stevenjb): Connection in progress. Show dialog? |
| 162 } |
| 163 } else { |
| 164 cros->ConnectToCellularNetwork(cellular); |
| 165 } |
| 166 } |
| 167 } |
| 168 |
| 169 void NetworkMenu::SetFirstLevelMenuWidth(int width) { |
| 170 gtk_widget_set_size_request(network_menu_.GetNativeMenu(), width, -1); |
| 171 } |
| 172 |
| 173 void NetworkMenu::CancelMenu() { |
| 174 network_menu_.CancelMenu(); |
| 175 } |
| 176 |
| 177 // static |
| 178 SkBitmap NetworkMenu::IconForNetworkStrength(int strength, bool black) { |
| 179 // Compose wifi icon by superimposing various icons. |
| 180 // NOTE: Use an array rather than just calculating a resource number to avoid |
| 181 // creating implicit ordering dependencies on the resource values. |
| 182 static const int kBarsImages[kNumWifiImages] = { |
| 183 IDR_STATUSBAR_NETWORK_BARS1, |
| 184 IDR_STATUSBAR_NETWORK_BARS2, |
| 185 IDR_STATUSBAR_NETWORK_BARS3, |
| 186 IDR_STATUSBAR_NETWORK_BARS4, |
| 187 IDR_STATUSBAR_NETWORK_BARS5, |
| 188 IDR_STATUSBAR_NETWORK_BARS6, |
| 189 IDR_STATUSBAR_NETWORK_BARS7, |
| 190 IDR_STATUSBAR_NETWORK_BARS8, |
| 191 IDR_STATUSBAR_NETWORK_BARS9, |
| 192 }; |
| 193 static const int kBarsBlackImages[kNumWifiImages] = { |
| 194 IDR_STATUSBAR_NETWORK_BARS1_BLACK, |
| 195 IDR_STATUSBAR_NETWORK_BARS2_BLACK, |
| 196 IDR_STATUSBAR_NETWORK_BARS3_BLACK, |
| 197 IDR_STATUSBAR_NETWORK_BARS4_BLACK, |
| 198 IDR_STATUSBAR_NETWORK_BARS5_BLACK, |
| 199 IDR_STATUSBAR_NETWORK_BARS6_BLACK, |
| 200 IDR_STATUSBAR_NETWORK_BARS7_BLACK, |
| 201 IDR_STATUSBAR_NETWORK_BARS8_BLACK, |
| 202 IDR_STATUSBAR_NETWORK_BARS9_BLACK, |
| 203 }; |
| 204 |
| 205 int index = static_cast<int>(strength / 100.0 * |
| 206 nextafter(static_cast<float>(kNumWifiImages), 0)); |
| 207 index = std::max(std::min(index, kNumWifiImages - 1), 0); |
| 208 return *ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 209 black ? kBarsBlackImages[index] : kBarsImages[index]); |
| 210 } |
| 211 |
| 212 // static |
| 213 SkBitmap NetworkMenu::IconForDisplay(SkBitmap icon, SkBitmap badge) { |
| 214 // Icons are 24x24. |
| 215 static const int kIconWidth = 24; |
| 216 static const int kIconHeight = 24; |
| 217 // Draw the network icon 3 pixels down to center it. |
| 218 static const int kIconX = 0; |
| 219 static const int kIconY = 3; |
| 220 // Draw badge at (14,14). |
| 221 static const int kBadgeX = 14; |
| 222 static const int kBadgeY = 14; |
| 223 |
| 224 gfx::CanvasSkia canvas(kIconWidth, kIconHeight, false); |
| 225 canvas.DrawBitmapInt(icon, kIconX, kIconY); |
| 226 if (!badge.empty()) |
| 227 canvas.DrawBitmapInt(badge, kBadgeX, kBadgeY); |
| 228 return canvas.ExtractBitmap(); |
| 229 } |
| 230 |
| 231 //////////////////////////////////////////////////////////////////////////////// |
| 232 // NetworkMenu, views::ViewMenuDelegate implementation: |
| 233 |
| 234 void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) { |
| 235 refreshing_menu_ = true; |
| 236 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
| 237 cros->RequestWifiScan(); |
| 238 cros->UpdateSystemInfo(); |
| 239 InitMenuItems(); |
| 240 network_menu_.Rebuild(); |
| 241 network_menu_.UpdateStates(); |
| 242 refreshing_menu_ = false; |
| 243 network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); |
| 244 } |
| 245 |
| 246 void NetworkMenu::InitMenuItems() { |
| 247 menu_items_.clear(); |
| 248 // Populate our MenuItems with the current list of wifi networks. |
| 249 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
| 250 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 251 |
| 252 // Ethernet |
| 253 string16 label = l10n_util::GetStringUTF16( |
| 254 IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); |
| 255 SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK); |
| 256 SkBitmap badge = cros->ethernet_connecting() || cros->ethernet_connected() ? |
| 257 SkBitmap() : *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED); |
| 258 int flag = (cros->ethernet_connecting() || cros->ethernet_connected()) ? |
| 259 FLAG_ETHERNET | FLAG_ASSOCIATED : FLAG_ETHERNET; |
| 260 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 261 IconForDisplay(icon, badge), std::string(), flag)); |
| 262 |
| 263 // Wifi |
| 264 const WifiNetworkVector& wifi_networks = cros->wifi_networks(); |
| 265 // Wifi networks ssids. |
| 266 for (size_t i = 0; i < wifi_networks.size(); ++i) { |
| 267 label = ASCIIToUTF16(wifi_networks[i].name()); |
| 268 SkBitmap icon = IconForNetworkStrength(wifi_networks[i].strength(), true); |
| 269 SkBitmap badge = wifi_networks[i].encrypted() ? |
| 270 *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : SkBitmap(); |
| 271 flag = (wifi_networks[i].name() == cros->wifi_name()) ? |
| 272 FLAG_WIFI | FLAG_ASSOCIATED : FLAG_WIFI; |
| 273 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 274 IconForDisplay(icon, badge), wifi_networks[i].service_path(), flag)); |
| 275 } |
| 276 |
| 277 // Cellular |
| 278 const CellularNetworkVector& cell_networks = cros->cellular_networks(); |
| 279 // Cellular networks ssids. |
| 280 for (size_t i = 0; i < cell_networks.size(); ++i) { |
| 281 label = ASCIIToUTF16(cell_networks[i].name()); |
| 282 SkBitmap icon = IconForNetworkStrength(cell_networks[i].strength(), true); |
| 283 // TODO(chocobo): Check cellular network 3g/edge. |
| 284 SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_3G); |
| 285 // SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_EDGE); |
| 286 flag = (cell_networks[i].name() == cros->cellular_name()) ? |
| 287 FLAG_CELLULAR | FLAG_ASSOCIATED : FLAG_CELLULAR; |
| 288 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 289 IconForDisplay(icon, badge), cell_networks[i].service_path(), flag)); |
| 290 } |
| 291 |
| 292 // No networks available message. |
| 293 if (wifi_networks.empty() && cell_networks.empty()) { |
| 294 label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT, |
| 295 l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE)); |
| 296 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 297 SkBitmap(), std::string(), FLAG_DISABLED)); |
| 298 } |
| 299 |
| 300 // Other networks |
| 301 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, |
| 302 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_NETWORKS), |
| 303 IconForDisplay(*rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0), |
| 304 SkBitmap()), |
| 305 std::string(), FLAG_OTHER_NETWORK)); |
| 306 |
| 307 if (cros->wifi_available() || cros->cellular_available()) { |
| 308 // Separator. |
| 309 menu_items_.push_back(MenuItem()); |
| 310 |
| 311 // Turn Wifi Off. (only if wifi available) |
| 312 if (cros->wifi_available()) { |
| 313 int id = cros->wifi_enabled() ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE : |
| 314 IDS_STATUSBAR_NETWORK_DEVICE_ENABLE; |
| 315 label = l10n_util::GetStringFUTF16(id, |
| 316 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI)); |
| 317 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 318 SkBitmap(), std::string(), FLAG_TOGGLE_WIFI)); |
| 319 } |
| 320 |
| 321 // Turn Cellular Off. (only if cellular available) |
| 322 if (cros->cellular_available()) { |
| 323 int id = cros->cellular_enabled() ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE : |
| 324 IDS_STATUSBAR_NETWORK_DEVICE_ENABLE; |
| 325 label = l10n_util::GetStringFUTF16(id, |
| 326 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CELLULAR)); |
| 327 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 328 SkBitmap(), std::string(), FLAG_TOGGLE_CELLULAR)); |
| 329 } |
| 330 } |
| 331 |
| 332 // TODO(chocobo): Uncomment once we figure out how to do offline mode. |
| 333 // Offline mode. |
| 334 // menu_items_.push_back(MenuItem(cros->offline_mode() ? |
| 335 // menus::MenuModel::TYPE_CHECK : menus::MenuModel::TYPE_COMMAND, |
| 336 // l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OFFLINE_MODE), |
| 337 // SkBitmap(), std::string(), FLAG_TOGGLE_OFFLINE)); |
| 338 |
| 339 if (cros->Connected() || ShouldOpenButtonOptions()) { |
| 340 // Separator. |
| 341 menu_items_.push_back(MenuItem()); |
| 342 |
| 343 // IP address |
| 344 if (cros->Connected()) { |
| 345 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, |
| 346 ASCIIToUTF16(cros->IPAddress()), SkBitmap(), |
| 347 std::string(), FLAG_DISABLED)); |
| 348 } |
| 349 |
| 350 // Network settings. |
| 351 if (ShouldOpenButtonOptions()) { |
| 352 label = |
| 353 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OPEN_OPTIONS_DIALOG); |
| 354 menu_items_.push_back(MenuItem(menus::MenuModel::TYPE_COMMAND, label, |
| 355 SkBitmap(), std::string(), FLAG_OPTIONS)); |
| 356 } |
| 357 } |
| 358 } |
| 359 |
| 360 } // namespace chromeos |
OLD | NEW |