network_menu.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2011 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 <algorithm> 8 9#include "base/command_line.h" 10#include "base/stringprintf.h" 11#include "base/utf_string_conversions.h" 12#include "chrome/browser/chromeos/cros/cros_library.h" 13#include "chrome/browser/chromeos/dom_ui/network_menu_ui.h" 14#include "chrome/browser/ui/browser.h" 15#include "chrome/browser/ui/browser_list.h" 16#include "chrome/common/chrome_switches.h" 17#include "chrome/common/url_constants.h" 18#include "chrome/browser/ui/views/window.h" 19#include "grit/generated_resources.h" 20#include "grit/theme_resources.h" 21#include "net/base/escape.h" 22#include "ui/base/l10n/l10n_util.h" 23#include "ui/base/resource/resource_bundle.h" 24#include "ui/gfx/canvas_skia.h" 25#include "ui/gfx/skbitmap_operations.h" 26#include "views/controls/menu/menu_2.h" 27#include "views/window/window.h" 28 29namespace { 30// Constants passed to Javascript: 31static const char* kNetworkTypeEthernet = "ethernet"; 32static const char* kNetworkTypeWifi = "wifi"; 33static const char* kNetworkTypeCellular = "cellular"; 34static const char* kNetworkTypeOther = "other"; 35 36static const char* kNetworkStatusConnected = "connected"; 37static const char* kNetworkStatusConnecting = "connecting"; 38static const char* kNetworkStatusDisconnected = "disconnected"; 39static const char* kNetworkStatusError = "error"; 40} 41 42namespace chromeos { 43 44//////////////////////////////////////////////////////////////////////////////// 45// NetworkMenu 46 47// static 48const int NetworkMenu::kNumBarsImages = 4; 49 50// NOTE: Use an array rather than just calculating a resource number to avoid 51// creating implicit ordering dependencies on the resource values. 52// static 53const int NetworkMenu::kBarsImages[kNumBarsImages] = { 54 IDR_STATUSBAR_NETWORK_BARS1, 55 IDR_STATUSBAR_NETWORK_BARS2, 56 IDR_STATUSBAR_NETWORK_BARS3, 57 IDR_STATUSBAR_NETWORK_BARS4, 58}; 59// static 60const int NetworkMenu::kBarsImagesBlack[kNumBarsImages] = { 61 IDR_STATUSBAR_NETWORK_BARS1_BLACK, 62 IDR_STATUSBAR_NETWORK_BARS2_BLACK, 63 IDR_STATUSBAR_NETWORK_BARS3_BLACK, 64 IDR_STATUSBAR_NETWORK_BARS4_BLACK, 65}; 66/* 67// static 68const int NetworkMenu::kBarsImagesLowData[kNumBarsImages] = { 69 IDR_STATUSBAR_NETWORK_BARS1_ORANGE, 70 IDR_STATUSBAR_NETWORK_BARS2_ORANGE, 71 IDR_STATUSBAR_NETWORK_BARS3_ORANGE, 72 IDR_STATUSBAR_NETWORK_BARS4_ORANGE, 73}; 74// static 75const int NetworkMenu::kBarsImagesVLowData[kNumBarsImages] = { 76 IDR_STATUSBAR_NETWORK_BARS1_RED, 77 IDR_STATUSBAR_NETWORK_BARS2_RED, 78 IDR_STATUSBAR_NETWORK_BARS3_RED, 79 IDR_STATUSBAR_NETWORK_BARS4_RED, 80}; 81*/ 82 83NetworkMenu::NetworkMenu() 84 : min_width_(-1) { 85 use_settings_ui_ = !CommandLine::ForCurrentProcess()->HasSwitch( 86 switches::kDisableTabbedOptions); 87 network_menu_.reset(NetworkMenuUI::CreateMenu2(this)); 88} 89 90NetworkMenu::~NetworkMenu() { 91} 92 93bool NetworkMenu::GetNetworkAt(int index, NetworkInfo* info) const { 94 DCHECK(info); 95 bool res = true; // True unless a network doesn't exist. 96 int flags = menu_items_[index].flags; 97 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 98 if (flags & FLAG_ETHERNET) { 99 info->network_type = kNetworkTypeEthernet; 100 if (cros->ethernet_connected()) { 101 info->status = kNetworkStatusConnected; 102 info->ip_address = cros->ethernet_network() ? 103 cros->ethernet_network()->ip_address() : std::string(); 104 } 105 info->need_passphrase = false; 106 info->remembered = true; 107 } else if (flags & FLAG_WIFI) { 108 WifiNetwork* wifi = cros->FindWifiNetworkByPath( 109 menu_items_[index].wireless_path); 110 if (wifi) { 111 info->network_type = kNetworkTypeWifi; 112 if (cros->wifi_network() && 113 wifi->service_path() == cros->wifi_network()->service_path()) { 114 if (cros->wifi_connected()) { 115 info->status = kNetworkStatusConnected; 116 info->message = l10n_util::GetStringUTF8( 117 IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED); 118 } else if (cros->wifi_connecting()) { 119 info->status = kNetworkStatusConnecting; 120 info->message = l10n_util::GetStringUTF8( 121 IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING); 122 } else if (wifi->state() == STATE_FAILURE) { 123 info->status = kNetworkStatusError; 124 info->message = wifi->GetErrorString(); 125 } else { 126 info->status = kNetworkStatusDisconnected; 127 info->message = l10n_util::GetStringUTF8( 128 IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED); 129 } 130 } else { 131 info->status = kNetworkStatusDisconnected; 132 info->message = l10n_util::GetStringUTF8( 133 IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED); 134 } 135 info->need_passphrase = wifi->IsPassphraseRequired(); 136 info->ip_address = wifi->ip_address(); 137 info->remembered = wifi->favorite(); 138 info->auto_connect = wifi->auto_connect(); 139 } else { 140 res = false; // Network not found, hide entry. 141 } 142 } else if (flags & FLAG_CELLULAR) { 143 CellularNetwork* cellular = cros->FindCellularNetworkByPath( 144 menu_items_[index].wireless_path); 145 if (cellular) { 146 info->network_type = kNetworkTypeCellular; 147 if (cros->cellular_network() && cellular->service_path() == 148 cros->cellular_network()->service_path()) { 149 if (cros->cellular_connected()) { 150 info->status = kNetworkStatusConnected; 151 info->message = l10n_util::GetStringUTF8( 152 IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED); 153 } else if (cros->cellular_connecting()) { 154 // TODO(stevenjb): Eliminate status message, or localize properly. 155 info->status = kNetworkStatusConnecting; 156 info->message = l10n_util::GetStringUTF8( 157 IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING) 158 + ": " + cellular->GetStateString(); 159 } else if (cellular->state() == STATE_FAILURE) { 160 info->status = kNetworkStatusError; 161 info->message = cellular->GetErrorString(); 162 } else { 163 info->status = kNetworkStatusDisconnected; 164 info->message = l10n_util::GetStringUTF8( 165 IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED); 166 } 167 } else { 168 info->status = kNetworkStatusDisconnected; 169 info->message = l10n_util::GetStringUTF8( 170 IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED); 171 } 172 info->ip_address = cellular->ip_address(); 173 info->need_passphrase = false; 174 info->remembered = true; 175 } else { 176 res = false; // Network not found, hide entry. 177 } 178 } else if (flags & FLAG_OTHER_NETWORK) { 179 info->status = kNetworkStatusDisconnected; 180 info->message = l10n_util::GetStringUTF8( 181 IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED); 182 info->network_type = kNetworkTypeOther; 183 info->need_passphrase = true; 184 info->remembered = true; 185 } else { 186 // Not a network, e.g options, separator. 187 } 188 return res; 189} 190 191bool NetworkMenu::ConnectToNetworkAt(int index, 192 const std::string& passphrase, 193 const std::string& ssid, 194 int auto_connect) const { 195 int flags = menu_items_[index].flags; 196 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 197 if (flags & FLAG_WIFI) { 198 WifiNetwork* wifi = cros->FindWifiNetworkByPath( 199 menu_items_[index].wireless_path); 200 if (wifi) { 201 // Connect or reconnect. 202 if (auto_connect >= 0) 203 wifi->set_auto_connect(auto_connect ? true : false); 204 if (wifi->connecting_or_connected()) { 205 // Show the config settings for the active network. 206 ShowTabbedNetworkSettings(wifi); 207 return true; 208 } 209 bool connected = false; 210 if (wifi->IsPassphraseRequired()) { 211 // Show the connection UI if we require a passphrase. 212 ShowNetworkConfigView(new NetworkConfigView(wifi)); 213 return true; 214 } else { 215 connected = cros->ConnectToWifiNetwork( 216 wifi, passphrase, std::string(), std::string()); 217 } 218 if (!connected) { 219 if (!MenuUI::IsEnabled()) { 220 // Show the wifi dialog on a failed attempt for non Web UI menus. 221 ShowNetworkConfigView(new NetworkConfigView(wifi)); 222 return true; 223 } else { 224 // If the connection attempt failed immediately (e.g. short password) 225 // keep the menu open so that a retry can be attempted. 226 return false; 227 } 228 } 229 } else { 230 // If we are attempting to connect to a network that no longer exists, 231 // display a notification. 232 // TODO(stevenjb): Show notification. 233 } 234 } else if (flags & FLAG_CELLULAR) { 235 CellularNetwork* cellular = cros->FindCellularNetworkByPath( 236 menu_items_[index].wireless_path); 237 if (cellular) { 238 if ((cellular->activation_state() != ACTIVATION_STATE_ACTIVATED && 239 cellular->activation_state() != ACTIVATION_STATE_UNKNOWN) || 240 cellular->needs_new_plan()) { 241 ActivateCellular(cellular); 242 return true; 243 } else if (cellular->connecting_or_connected()) { 244 // Cellular network is connecting or connected, 245 // so we show the config settings for the cellular network. 246 ShowTabbedNetworkSettings(cellular); 247 return true; 248 } 249 // Clicked on a disconnected cellular network, so connect to it. 250 cros->ConnectToCellularNetwork(cellular); 251 } else { 252 // If we are attempting to connect to a network that no longer exists, 253 // display a notification. 254 // TODO(stevenjb): Show notification. 255 } 256 } else if (flags & FLAG_OTHER_NETWORK) { 257 bool connected = false; 258 if (MenuUI::IsEnabled()) { 259 // default is true 260 bool auto_connect_bool = auto_connect == 0 ? false : true; 261 connected = cros->ConnectToWifiNetwork( 262 passphrase.empty() ? SECURITY_NONE : SECURITY_UNKNOWN, 263 ssid, passphrase, std::string(), std::string(), auto_connect_bool); 264 } 265 if (!connected) { 266 ShowOther(); 267 } 268 } 269 return true; 270} 271 272//////////////////////////////////////////////////////////////////////////////// 273// NetworkMenu, ui::MenuModel implementation: 274 275int NetworkMenu::GetItemCount() const { 276 return static_cast<int>(menu_items_.size()); 277} 278 279ui::MenuModel::ItemType NetworkMenu::GetTypeAt(int index) const { 280 return menu_items_[index].type; 281} 282 283string16 NetworkMenu::GetLabelAt(int index) const { 284 return menu_items_[index].label; 285} 286 287const gfx::Font* NetworkMenu::GetLabelFontAt(int index) const { 288 return (menu_items_[index].flags & FLAG_ASSOCIATED) ? 289 &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) : 290 NULL; 291} 292 293bool NetworkMenu::IsItemCheckedAt(int index) const { 294 // All ui::MenuModel::TYPE_CHECK menu items are checked. 295 return true; 296} 297 298bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) const { 299 if (!menu_items_[index].icon.empty()) { 300 *icon = menu_items_[index].icon; 301 return true; 302 } 303 return false; 304} 305 306bool NetworkMenu::IsEnabledAt(int index) const { 307 return !(menu_items_[index].flags & FLAG_DISABLED); 308} 309 310void NetworkMenu::ActivatedAt(int index) { 311 // When we are refreshing the menu, ignore menu item activation. 312 if (refreshing_menu_) 313 return; 314 315 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 316 int flags = menu_items_[index].flags; 317 if (flags & FLAG_OPTIONS) { 318 OpenButtonOptions(); 319 } else if (flags & FLAG_TOGGLE_ETHERNET) { 320 cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled()); 321 } else if (flags & FLAG_TOGGLE_WIFI) { 322 cros->EnableWifiNetworkDevice(!cros->wifi_enabled()); 323 } else if (flags & FLAG_TOGGLE_CELLULAR) { 324 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); 325 } else if (flags & FLAG_TOGGLE_OFFLINE) { 326 cros->EnableOfflineMode(!cros->offline_mode()); 327 } else if (flags & FLAG_ETHERNET) { 328 if (cros->ethernet_connected()) { 329 ShowTabbedNetworkSettings(cros->ethernet_network()); 330 } 331 } else if (flags & FLAG_WIFI) { 332 ConnectToNetworkAt(index, std::string(), std::string(), -1); 333 } else if (flags & FLAG_OTHER_NETWORK) { 334 ConnectToNetworkAt(index, std::string(), std::string(), -1); 335 } else if (flags & FLAG_CELLULAR) { 336 ConnectToNetworkAt(index, std::string(), std::string(), -1); 337 } 338} 339 340void NetworkMenu::SetFirstLevelMenuWidth(int width) { 341 min_width_ = width; 342 // This actually has no effect since menu is rebuilt before showing. 343 network_menu_->SetMinimumWidth(width); 344} 345 346void NetworkMenu::CancelMenu() { 347 network_menu_->CancelMenu(); 348} 349 350void NetworkMenu::UpdateMenu() { 351 refreshing_menu_ = true; 352 InitMenuItems(); 353 network_menu_->Rebuild(); 354 refreshing_menu_ = false; 355} 356 357// static 358SkBitmap NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi, 359 bool black) { 360 DCHECK(wifi); 361 if (wifi->strength() == 0) { 362 return *ResourceBundle::GetSharedInstance().GetBitmapNamed( 363 black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : 364 IDR_STATUSBAR_NETWORK_BARS0); 365 } 366 int index = static_cast<int>(wifi->strength() / 100.0 * 367 nextafter(static_cast<float>(kNumBarsImages), 0)); 368 index = std::max(std::min(index, kNumBarsImages - 1), 0); 369 const int* images = black ? kBarsImagesBlack : kBarsImages; 370 return *ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]); 371} 372 373// static 374SkBitmap NetworkMenu::IconForNetworkStrength(const CellularNetwork* cellular, 375 bool black) { 376 DCHECK(cellular); 377 // If no data, then we show 0 bars. 378 if (cellular->strength() == 0 || 379 cellular->GetDataLeft() == CellularNetwork::DATA_NONE) { 380 return *ResourceBundle::GetSharedInstance().GetBitmapNamed( 381 black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : 382 IDR_STATUSBAR_NETWORK_BARS0); 383 } 384 int index = static_cast<int>(cellular->strength() / 100.0 * 385 nextafter(static_cast<float>(kNumBarsImages), 0)); 386 index = std::max(std::min(index, kNumBarsImages - 1), 0); 387 const int* images = black ? kBarsImagesBlack : kBarsImages; 388 return *ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]); 389} 390 391// static 392SkBitmap NetworkMenu::IconForNetworkConnecting(double animation_value, 393 bool black) { 394 // Draw animation of bars icon fading in and out. 395 // We are fading between 0 bars and a third of the opacity of 4 bars. 396 // Use the current value of the animation to calculate the alpha value 397 // of how transparent the icon is. 398 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 399 return SkBitmapOperations::CreateBlendedBitmap( 400 *rb.GetBitmapNamed(black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : 401 IDR_STATUSBAR_NETWORK_BARS0), 402 *rb.GetBitmapNamed(black ? IDR_STATUSBAR_NETWORK_BARS4_BLACK : 403 IDR_STATUSBAR_NETWORK_BARS4), 404 animation_value / 3); 405} 406 407// static 408// TODO(ers) update for GSM when we have the necessary images 409SkBitmap NetworkMenu::BadgeForNetworkTechnology( 410 const CellularNetwork* cellular) { 411 if (!cellular) 412 return SkBitmap(); 413 414 int id = -1; 415 if (cellular->network_technology() == NETWORK_TECHNOLOGY_EVDO) { 416 switch (cellular->GetDataLeft()) { 417 case CellularNetwork::DATA_NONE: 418 id = IDR_STATUSBAR_NETWORK_3G_ERROR; 419 break; 420 case CellularNetwork::DATA_VERY_LOW: 421 case CellularNetwork::DATA_LOW: 422 case CellularNetwork::DATA_NORMAL: 423 id = IDR_STATUSBAR_NETWORK_3G; 424 break; 425 case CellularNetwork::DATA_UNKNOWN: 426 id = IDR_STATUSBAR_NETWORK_3G_UNKNOWN; 427 break; 428 } 429 } else if (cellular->network_technology() == NETWORK_TECHNOLOGY_1XRTT) { 430 switch (cellular->GetDataLeft()) { 431 case CellularNetwork::DATA_NONE: 432 id = IDR_STATUSBAR_NETWORK_1X_ERROR; 433 break; 434 case CellularNetwork::DATA_VERY_LOW: 435 case CellularNetwork::DATA_LOW: 436 case CellularNetwork::DATA_NORMAL: 437 id = IDR_STATUSBAR_NETWORK_1X; 438 break; 439 case CellularNetwork::DATA_UNKNOWN: 440 id = IDR_STATUSBAR_NETWORK_1X_UNKNOWN; 441 break; 442 } 443 } 444 if (id == -1) 445 return SkBitmap(); 446 else 447 return *ResourceBundle::GetSharedInstance().GetBitmapNamed(id); 448} 449 450// static 451SkBitmap NetworkMenu::IconForDisplay(SkBitmap icon, SkBitmap badge) { 452 // Draw badge at (14,14). 453 static const int kBadgeX = 14; 454 static const int kBadgeY = 14; 455 456 gfx::CanvasSkia canvas(icon.width(), icon.height(), false); 457 canvas.DrawBitmapInt(icon, 0, 0); 458 if (!badge.empty()) 459 canvas.DrawBitmapInt(badge, kBadgeX, kBadgeY); 460 return canvas.ExtractBitmap(); 461} 462 463//////////////////////////////////////////////////////////////////////////////// 464// NetworkMenu, views::ViewMenuDelegate implementation: 465 466void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) { 467 refreshing_menu_ = true; 468 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 469 cros->RequestWifiScan(); 470 471 // Build initial menu items. They will be updated when UpdateMenu is 472 // called from NetworkChanged. 473 InitMenuItems(); 474 network_menu_->Rebuild(); 475 476 // Restore menu width, if it was set up. 477 // NOTE: width isn't checked for correctness here since all width-related 478 // logic implemented inside |network_menu_|. 479 if (min_width_ != -1) 480 network_menu_->SetMinimumWidth(min_width_); 481 refreshing_menu_ = false; 482 network_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); 483} 484 485void NetworkMenu::InitMenuItems() { 486 // This gets called on initialization, so any changes should be reflected 487 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). 488 489 menu_items_.clear(); 490 // Populate our MenuItems with the current list of wifi networks. 491 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); 492 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 493 494 string16 label; 495 496 if (cros->IsLocked()) { 497 label = l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_LOCKED); 498 menu_items_.push_back( 499 MenuItem(ui::MenuModel::TYPE_COMMAND, 500 label, SkBitmap(), 501 std::string(), FLAG_DISABLED)); 502 return; 503 } 504 505 // Ethernet 506 bool ethernet_available = cros->ethernet_available(); 507 bool ethernet_enabled = cros->ethernet_enabled(); 508 if (ethernet_available && ethernet_enabled) { 509 bool ethernet_connected = cros->ethernet_connected(); 510 bool ethernet_connecting = cros->ethernet_connecting(); 511 512 if (ethernet_connecting) { 513 label = l10n_util::GetStringFUTF16( 514 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 515 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET), 516 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)); 517 } else { 518 label = l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); 519 } 520 SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK); 521 SkBitmap badge = ethernet_connecting || ethernet_connected ? 522 SkBitmap() : *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED); 523 int flag = FLAG_ETHERNET; 524 if (ethernet_connecting || ethernet_connected) 525 flag |= FLAG_ASSOCIATED; 526 menu_items_.push_back( 527 MenuItem(ui::MenuModel::TYPE_COMMAND, label, 528 IconForDisplay(icon, badge), std::string(), flag)); 529 } 530 531 // Wifi Networks 532 bool wifi_available = cros->wifi_available(); 533 bool wifi_enabled = cros->wifi_enabled(); 534 if (wifi_available && wifi_enabled) { 535 const WifiNetworkVector& wifi_networks = cros->wifi_networks(); 536 const WifiNetwork* active_wifi = cros->wifi_network(); 537 538 bool separator_added = false; 539 // List Wifi networks. 540 for (size_t i = 0; i < wifi_networks.size(); ++i) { 541 if (wifi_networks[i]->connecting()) { 542 label = l10n_util::GetStringFUTF16( 543 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 544 ASCIIToUTF16(wifi_networks[i]->name()), 545 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)); 546 } else { 547 label = ASCIIToUTF16(wifi_networks[i]->name()); 548 } 549 550 // First add a separator if necessary. 551 if (!separator_added) { 552 separator_added = true; 553 if (!menu_items_.empty()) { // Don't add if first menu item. 554 menu_items_.push_back(MenuItem()); // Separator 555 } 556 } 557 558 SkBitmap icon = IconForNetworkStrength(wifi_networks[i], true); 559 SkBitmap badge = wifi_networks[i]->encrypted() ? 560 *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : SkBitmap(); 561 int flag = FLAG_WIFI; 562 if (!wifi_networks[i]->connectable()) 563 flag |= FLAG_DISABLED; 564 if (active_wifi 565 && wifi_networks[i]->service_path() == active_wifi->service_path()) 566 flag |= FLAG_ASSOCIATED; 567 menu_items_.push_back( 568 MenuItem(ui::MenuModel::TYPE_COMMAND, label, 569 IconForDisplay(icon, badge), 570 wifi_networks[i]->service_path(), flag)); 571 } 572 } 573 574 // Cellular Networks 575 bool cellular_available = cros->cellular_available(); 576 bool cellular_enabled = cros->cellular_enabled(); 577 if (cellular_available && cellular_enabled) { 578 const CellularNetworkVector& cell_networks = cros->cellular_networks(); 579 const CellularNetwork* active_cellular = cros->cellular_network(); 580 581 bool separator_added = false; 582 // List Cellular networks. 583 for (size_t i = 0; i < cell_networks.size(); ++i) { 584 chromeos::ActivationState activation_state = 585 cell_networks[i]->activation_state(); 586 587 // If we are on the OOBE/login screen, do not show activating 3G option. 588 if (!IsBrowserMode() && activation_state != ACTIVATION_STATE_ACTIVATED) 589 continue; 590 591 if (activation_state == ACTIVATION_STATE_NOT_ACTIVATED || 592 activation_state == ACTIVATION_STATE_PARTIALLY_ACTIVATED) { 593 label = l10n_util::GetStringFUTF16( 594 IDS_STATUSBAR_NETWORK_DEVICE_ACTIVATE, 595 ASCIIToUTF16(cell_networks[i]->name())); 596 } else if (activation_state == ACTIVATION_STATE_ACTIVATING) { 597 label = l10n_util::GetStringFUTF16( 598 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 599 ASCIIToUTF16(cell_networks[i]->name()), 600 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ACTIVATING)); 601 } else if (cell_networks[i]->connecting()) { 602 label = l10n_util::GetStringFUTF16( 603 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 604 ASCIIToUTF16(cell_networks[i]->name()), 605 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)); 606 } else { 607 label = ASCIIToUTF16(cell_networks[i]->name()); 608 } 609 610 // First add a separator if necessary. 611 if (!separator_added) { 612 separator_added = true; 613 if (!menu_items_.empty()) { // Don't add if first menu item. 614 menu_items_.push_back(MenuItem()); // Separator 615 } 616 } 617 618 SkBitmap icon = IconForNetworkStrength(cell_networks[i], true); 619 SkBitmap badge = BadgeForNetworkTechnology(cell_networks[i]); 620 int flag = FLAG_CELLULAR; 621 if (!cell_networks[i]->connectable()) 622 flag |= FLAG_DISABLED; 623 bool isActive = active_cellular && 624 cell_networks[i]->service_path() == active_cellular->service_path() && 625 (cell_networks[i]->connecting() || cell_networks[i]->connected()); 626 if (isActive) 627 flag |= FLAG_ASSOCIATED; 628 menu_items_.push_back( 629 MenuItem(ui::MenuModel::TYPE_COMMAND, label, 630 IconForDisplay(icon, badge), 631 cell_networks[i]->service_path(), flag)); 632 if (isActive) { 633 label.clear(); 634 if (active_cellular->needs_new_plan()) { 635 label = l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_NO_PLAN_LABEL); 636 } else { 637 const chromeos::CellularDataPlan* plan = 638 active_cellular->GetSignificantDataPlan(); 639 if (plan) 640 label = plan->GetUsageInfo(); 641 } 642 if (label.length()) { 643 menu_items_.push_back( 644 MenuItem(ui::MenuModel::TYPE_COMMAND, 645 label, SkBitmap(), 646 std::string(), FLAG_DISABLED)); 647 } 648 } 649 } 650 } 651 652 // No networks available message. 653 if (menu_items_.empty()) { 654 label = l10n_util::GetStringFUTF16(IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT, 655 l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE)); 656 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 657 SkBitmap(), std::string(), FLAG_DISABLED)); 658 } 659 660 // Add network. 661 if (wifi_available && wifi_enabled) { 662 menu_items_.push_back(MenuItem()); // Separator 663 menu_items_.push_back(MenuItem( 664 ui::MenuModel::TYPE_COMMAND, 665 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_NETWORKS), 666 IconForDisplay(*rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0_BLACK), 667 SkBitmap()), 668 std::string(), FLAG_OTHER_NETWORK)); 669 } 670 671 // Enable / disable wireless. 672 if (wifi_available || cellular_available) { 673 menu_items_.push_back(MenuItem()); // Separator 674 675 if (wifi_available) { 676 // Add 'Scanning...' 677 if (cros->wifi_scanning()) { 678 label = l10n_util::GetStringUTF16(IDS_STATUSBAR_WIFI_SCANNING_MESSAGE); 679 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 680 SkBitmap(), std::string(), FLAG_DISABLED)); 681 } 682 683 int id = wifi_enabled ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE : 684 IDS_STATUSBAR_NETWORK_DEVICE_ENABLE; 685 label = l10n_util::GetStringFUTF16(id, 686 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI)); 687 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 688 SkBitmap(), std::string(), FLAG_TOGGLE_WIFI)); 689 } 690 691 if (cellular_available) { 692 int id = cellular_enabled ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE : 693 IDS_STATUSBAR_NETWORK_DEVICE_ENABLE; 694 label = l10n_util::GetStringFUTF16(id, 695 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CELLULAR)); 696 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 697 SkBitmap(), std::string(), FLAG_TOGGLE_CELLULAR)); 698 } 699 } 700 701 // Offline mode. 702 // TODO(chocobo): Uncomment once we figure out how to do offline mode. 703 // menu_items_.push_back(MenuItem(cros->offline_mode() ? 704 // ui::MenuModel::TYPE_CHECK : ui::MenuModel::TYPE_COMMAND, 705 // l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_OFFLINE_MODE), 706 // SkBitmap(), std::string(), FLAG_TOGGLE_OFFLINE)); 707 708 bool connected = cros->Connected(); // always call for test expectations. 709 bool oobe = !ShouldOpenButtonOptions(); // we don't show options for OOBE. 710 // Network settings. (And IP Address) 711 if (!oobe) { 712 menu_items_.push_back(MenuItem()); // Separator 713 714 if (!MenuUI::IsEnabled() && connected) { 715 std::string ip_address = cros->IPAddress(); 716 if (!ip_address.empty()) { 717 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, 718 ASCIIToUTF16(cros->IPAddress()), SkBitmap(), std::string(), 719 FLAG_DISABLED)); 720 } 721 } 722 723 label = l10n_util::GetStringUTF16(IsBrowserMode() ? 724 IDS_STATUSBAR_NETWORK_OPEN_OPTIONS_DIALOG : 725 IDS_STATUSBAR_NETWORK_OPEN_PROXY_SETTINGS_DIALOG); 726 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 727 SkBitmap(), std::string(), FLAG_OPTIONS)); 728 } 729} 730 731void NetworkMenu::ShowTabbedNetworkSettings(const Network* network) const { 732 DCHECK(network); 733 Browser* browser = BrowserList::GetLastActive(); 734 if (!browser) 735 return; 736 std::string page = StringPrintf("%s?servicePath=%s&networkType=%d", 737 chrome::kInternetOptionsSubPage, 738 EscapeUrlEncodedData(network->service_path()).c_str(), 739 network->type()); 740 browser->ShowOptionsTab(page); 741} 742 743// TODO(stevenjb): deprecate this once we've committed to tabbed settings 744// and the embedded menu UI (and fully deprecated NetworkConfigView). 745// Meanwhile, if MenuUI::IsEnabled() is true, always show the settings UI, 746// otherwise show NetworkConfigView only to get passwords when not connected. 747void NetworkMenu::ShowNetworkConfigView(NetworkConfigView* view) const { 748 view->set_browser_mode(IsBrowserMode()); 749 views::Window* window = browser::CreateViewsWindow( 750 GetNativeWindow(), gfx::Rect(), view); 751 window->SetIsAlwaysOnTop(true); 752 window->Show(); 753} 754 755void NetworkMenu::ActivateCellular(const CellularNetwork* cellular) const { 756 DCHECK(cellular); 757 Browser* browser = BrowserList::GetLastActive(); 758 if (!browser) 759 return; 760 browser->OpenMobilePlanTabAndActivate(); 761} 762 763void NetworkMenu::ShowOther() const { 764 if (use_settings_ui_ && MenuUI::IsEnabled()) { 765 Browser* browser = BrowserList::GetLastActive(); 766 if (browser) { 767 std::string page = StringPrintf("%s?networkType=%d", 768 chrome::kInternetOptionsSubPage, 769 chromeos::TYPE_WIFI); 770 browser->ShowOptionsTab(page); 771 } 772 } else { 773 ShowNetworkConfigView(new NetworkConfigView()); 774 } 775} 776 777} // namespace chromeos 778