network_menu.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
1// Copyright (c) 2012 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 "ash/shell.h" 10#include "ash/shell_delegate.h" 11#include "ash/system/chromeos/network/network_icon.h" 12#include "base/bind.h" 13#include "base/logging.h" 14#include "base/strings/stringprintf.h" 15#include "base/strings/utf_string_conversions.h" 16#include "chrome/browser/chromeos/choose_mobile_network_dialog.h" 17#include "chrome/browser/chromeos/login/user_manager.h" 18#include "chrome/browser/chromeos/mobile_config.h" 19#include "chrome/browser/chromeos/options/network_config_view.h" 20#include "chrome/browser/chromeos/options/network_connect.h" 21#include "chrome/browser/defaults.h" 22#include "chrome/browser/profiles/profile_manager.h" 23#include "chrome/common/url_constants.h" 24#include "chromeos/network/device_state.h" 25#include "chromeos/network/network_state.h" 26#include "chromeos/network/network_state_handler.h" 27#include "grit/ash_resources.h" 28#include "grit/ash_strings.h" 29#include "grit/generated_resources.h" 30#include "third_party/cros_system_api/dbus/service_constants.h" 31#include "ui/base/l10n/l10n_util.h" 32#include "ui/base/models/menu_model.h" 33#include "ui/base/resource/resource_bundle.h" 34#include "ui/gfx/image/image_skia.h" 35 36namespace chromeos { 37 38namespace { 39 40// Offsets for views menu ids (main menu and submenu ids use the same 41// namespace). 42const int kMainIndexMask = 0x1000; 43const int kMoreIndexMask = 0x4000; 44 45// Replace '&' in a string with "&&" to allow it to be a menu item label. 46std::string EscapeAmpersands(const std::string& input) { 47 std::string str = input; 48 size_t found = str.find('&'); 49 while (found != std::string::npos) { 50 str.replace(found, 1, "&&"); 51 found = str.find('&', found + 2); 52 } 53 return str; 54} 55 56// Highlight any connected or connecting networks in the UI. 57bool ShouldHighlightNetwork(const NetworkState* network) { 58 return network->IsConnectedState() || network->IsConnectingState(); 59} 60 61void ToggleTechnology(const std::string& technology) { 62 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); 63 bool is_enabled = handler->IsTechnologyEnabled(technology); 64 handler->SetTechnologyEnabled(technology, !is_enabled, 65 network_handler::ErrorCallback()); 66} 67 68} // namespace 69 70class NetworkMenuModel : public ui::MenuModel { 71 public: 72 struct MenuItem { 73 MenuItem() 74 : type(ui::MenuModel::TYPE_SEPARATOR), 75 sub_menu_model(NULL), 76 flags(0) { 77 } 78 MenuItem(ui::MenuModel::ItemType type, string16 label, gfx::ImageSkia icon, 79 const std::string& service_path, int flags) 80 : type(type), 81 label(label), 82 icon(icon), 83 service_path(service_path), 84 sub_menu_model(NULL), 85 flags(flags) { 86 } 87 MenuItem(ui::MenuModel::ItemType type, string16 label, gfx::ImageSkia icon, 88 NetworkMenuModel* sub_menu_model, int flags) 89 : type(type), 90 label(label), 91 icon(icon), 92 sub_menu_model(sub_menu_model), 93 flags(flags) { 94 } 95 96 ui::MenuModel::ItemType type; 97 string16 label; 98 gfx::ImageSkia icon; 99 std::string service_path; 100 NetworkMenuModel* sub_menu_model; // Weak ptr. 101 int flags; 102 }; 103 typedef std::vector<MenuItem> MenuItemVector; 104 105 explicit NetworkMenuModel(const base::WeakPtr<NetworkMenu>& owner) 106 : owner_(owner) {} 107 virtual ~NetworkMenuModel() {} 108 109 // Connect or reconnect to the network at |index|. 110 void ConnectToNetworkAt(int index); 111 112 // Called by NetworkMenu::UpdateMenu to initialize menu items. 113 virtual void InitMenuItems(bool should_open_button_options) = 0; 114 115 // Menu item field accessors. 116 const MenuItemVector& menu_items() const { return menu_items_; } 117 118 // ui::MenuModel implementation 119 // GetCommandIdAt() must be implemented by subclasses. 120 virtual bool HasIcons() const OVERRIDE; 121 virtual int GetItemCount() const OVERRIDE; 122 virtual ui::MenuModel::ItemType GetTypeAt(int index) const OVERRIDE; 123 virtual ui::MenuSeparatorType GetSeparatorTypeAt(int index) const OVERRIDE; 124 virtual string16 GetLabelAt(int index) const OVERRIDE; 125 virtual bool IsItemDynamicAt(int index) const OVERRIDE; 126 virtual const gfx::Font* GetLabelFontAt(int index) const OVERRIDE; 127 virtual bool GetAcceleratorAt(int index, 128 ui::Accelerator* accelerator) const OVERRIDE; 129 virtual bool IsItemCheckedAt(int index) const OVERRIDE; 130 virtual int GetGroupIdAt(int index) const OVERRIDE; 131 virtual bool GetIconAt(int index, gfx::Image* icon) OVERRIDE; 132 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt( 133 int index) const OVERRIDE; 134 virtual bool IsEnabledAt(int index) const OVERRIDE; 135 virtual bool IsVisibleAt(int index) const OVERRIDE; 136 virtual ui::MenuModel* GetSubmenuModelAt(int index) const OVERRIDE; 137 virtual void HighlightChangedTo(int index) OVERRIDE; 138 virtual void ActivatedAt(int index) OVERRIDE; 139 virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) OVERRIDE; 140 virtual ui::MenuModelDelegate* GetMenuModelDelegate() const OVERRIDE; 141 142 protected: 143 enum MenuItemFlags { 144 FLAG_NONE = 0, 145 FLAG_DISABLED = 1 << 0, 146 FLAG_TOGGLE_WIFI = 1 << 2, 147 FLAG_TOGGLE_MOBILE = 1 << 3, 148 FLAG_ASSOCIATED = 1 << 5, 149 FLAG_ETHERNET = 1 << 6, 150 FLAG_WIFI = 1 << 7, 151 FLAG_WIMAX = 1 << 8, 152 FLAG_CELLULAR = 1 << 9, 153 FLAG_OPTIONS = 1 << 10, 154 FLAG_ADD_WIFI = 1 << 11, 155 FLAG_ADD_CELLULAR = 1 << 12, 156 }; 157 158 // Our menu items. 159 MenuItemVector menu_items_; 160 161 // Weak pointer to NetworkMenu that owns this MenuModel. 162 base::WeakPtr<NetworkMenu> owner_; 163 164 // Top up URL of the current carrier on empty string if there's none. 165 std::string top_up_url_; 166 167 // Carrier ID which top up URL is initialized for. 168 // Used to update top up URL only when cellular carrier has changed. 169 std::string carrier_id_; 170 171 private: 172 // Open a dialog to set up and connect to a network. 173 void ShowOther(const std::string& type) const; 174 175 DISALLOW_COPY_AND_ASSIGN(NetworkMenuModel); 176}; 177 178class MoreMenuModel : public NetworkMenuModel { 179 public: 180 explicit MoreMenuModel(const base::WeakPtr<NetworkMenu> owner) 181 : NetworkMenuModel(owner) {} 182 virtual ~MoreMenuModel() {} 183 184 // NetworkMenuModel implementation. 185 virtual void InitMenuItems(bool should_open_button_options) OVERRIDE; 186 187 // ui::MenuModel implementation 188 virtual int GetCommandIdAt(int index) const OVERRIDE; 189 190 private: 191 DISALLOW_COPY_AND_ASSIGN(MoreMenuModel); 192}; 193 194class MainMenuModel : public NetworkMenuModel { 195 public: 196 explicit MainMenuModel(const base::WeakPtr<NetworkMenu>& owner) 197 : NetworkMenuModel(owner), 198 more_menu_model_(new MoreMenuModel(owner)) { 199 } 200 virtual ~MainMenuModel() {} 201 202 // NetworkMenuModel implementation. 203 virtual void InitMenuItems(bool should_open_button_options) OVERRIDE; 204 205 // ui::MenuModel implementation 206 virtual int GetCommandIdAt(int index) const OVERRIDE; 207 208 private: 209 void AddWirelessNetworkMenuItem(const NetworkState* wifi_network, int flag); 210 void AddMessageItem(const string16& msg); 211 212 scoped_ptr<MoreMenuModel> more_menu_model_; 213 214 DISALLOW_COPY_AND_ASSIGN(MainMenuModel); 215}; 216 217//////////////////////////////////////////////////////////////////////////////// 218// NetworkMenuModel, public methods: 219 220void NetworkMenuModel::ConnectToNetworkAt(int index) { 221 const std::string& service_path = menu_items_[index].service_path; 222 network_connect::ConnectResult result = 223 network_connect::ConnectToNetwork( 224 service_path, owner_->delegate()->GetNativeWindow()); 225 if (result == network_connect::NETWORK_NOT_FOUND) { 226 // If we are attempting to connect to a network that no longer exists, 227 // display a notification. 228 LOG(WARNING) << "Network does not exist to connect to: " 229 << service_path; 230 // TODO(stevenjb): Show notification. 231 } 232} 233 234//////////////////////////////////////////////////////////////////////////////// 235// NetworkMenuModel, ui::MenuModel implementation: 236 237bool NetworkMenuModel::HasIcons() const { 238 return true; 239} 240 241int NetworkMenuModel::GetItemCount() const { 242 return static_cast<int>(menu_items_.size()); 243} 244 245ui::MenuModel::ItemType NetworkMenuModel::GetTypeAt(int index) const { 246 return menu_items_[index].type; 247} 248 249ui::MenuSeparatorType NetworkMenuModel::GetSeparatorTypeAt(int index) const { 250 return ui::NORMAL_SEPARATOR; 251} 252 253string16 NetworkMenuModel::GetLabelAt(int index) const { 254 return menu_items_[index].label; 255} 256 257bool NetworkMenuModel::IsItemDynamicAt(int index) const { 258 return false; 259} 260 261const gfx::Font* NetworkMenuModel::GetLabelFontAt(int index) const { 262 const gfx::Font* font = NULL; 263 if (menu_items_[index].flags & FLAG_ASSOCIATED) { 264 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); 265 font = &resource_bundle.GetFont( 266 browser_defaults::kAssociatedNetworkFontStyle); 267 } 268 269 return font; 270} 271 272bool NetworkMenuModel::GetAcceleratorAt(int index, 273 ui::Accelerator* accelerator) const { 274 return false; 275} 276 277bool NetworkMenuModel::IsItemCheckedAt(int index) const { 278 // All ui::MenuModel::TYPE_CHECK menu items are checked. 279 return true; 280} 281 282int NetworkMenuModel::GetGroupIdAt(int index) const { 283 return 0; 284} 285 286bool NetworkMenuModel::GetIconAt(int index, gfx::Image* icon) { 287 if (!menu_items_[index].icon.isNull()) { 288 *icon = gfx::Image(menu_items_[index].icon); 289 return true; 290 } 291 return false; 292} 293 294ui::ButtonMenuItemModel* NetworkMenuModel::GetButtonMenuItemAt( 295 int index) const { 296 return NULL; 297} 298 299bool NetworkMenuModel::IsEnabledAt(int index) const { 300 return !(menu_items_[index].flags & FLAG_DISABLED); 301} 302 303bool NetworkMenuModel::IsVisibleAt(int index) const { 304 return true; 305} 306 307ui::MenuModel* NetworkMenuModel::GetSubmenuModelAt(int index) const { 308 return menu_items_[index].sub_menu_model; 309} 310 311void NetworkMenuModel::HighlightChangedTo(int index) { 312} 313 314void NetworkMenuModel::ActivatedAt(int index) { 315 // When we are refreshing the menu, ignore menu item activation. 316 if (owner_->refreshing_menu_) 317 return; 318 319 int flags = menu_items_[index].flags; 320 if (flags & FLAG_OPTIONS) { 321 owner_->delegate()->OpenButtonOptions(); 322 } else if (flags & FLAG_TOGGLE_WIFI) { 323 ToggleTechnology(flimflam::kTypeWifi); 324 } else if (flags & FLAG_TOGGLE_MOBILE) { 325 ToggleTechnology(NetworkStateHandler::kMatchTypeMobile); 326 } else if (flags & FLAG_ETHERNET) { 327 // Do nothing (used in login screen only) 328 } else if (flags & (FLAG_WIFI | FLAG_WIMAX | FLAG_CELLULAR)) { 329 ConnectToNetworkAt(index); 330 } else if (flags & FLAG_ADD_WIFI) { 331 ShowOther(flimflam::kTypeWifi); 332 } else if (flags & FLAG_ADD_CELLULAR) { 333 ShowOther(flimflam::kTypeCellular); 334 } 335} 336 337void NetworkMenuModel::SetMenuModelDelegate(ui::MenuModelDelegate* delegate) { 338} 339 340ui::MenuModelDelegate* NetworkMenuModel::GetMenuModelDelegate() const { 341 return NULL; 342} 343 344//////////////////////////////////////////////////////////////////////////////// 345// NetworkMenuModel, private methods: 346 347void NetworkMenuModel::ShowOther(const std::string& type) const { 348 gfx::NativeWindow native_window = owner_->delegate()->GetNativeWindow(); 349 if (type == flimflam::kTypeCellular) 350 ChooseMobileNetworkDialog::ShowDialog(native_window); 351 else 352 NetworkConfigView::ShowForType(chromeos::TYPE_WIFI, native_window); 353} 354 355//////////////////////////////////////////////////////////////////////////////// 356// MainMenuModel 357 358void MainMenuModel::AddWirelessNetworkMenuItem(const NetworkState* network, 359 int flag) { 360 string16 label; 361 // Ampersand is a valid character in an SSID, but menu2 uses it to mark 362 // "mnemonics" for keyboard shortcuts. 363 std::string wifi_name = EscapeAmpersands(network->name()); 364 if (network->IsConnectingState()) { 365 label = l10n_util::GetStringFUTF16( 366 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 367 UTF8ToUTF16(wifi_name), 368 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)); 369 } else { 370 label = UTF8ToUTF16(wifi_name); 371 } 372 373 // We do not have convenient access to whether or not it might be possible 374 // to connect to a wireless network (e.g. whether certs are required), so all 375 // entries are enabled. 376 377 if (ShouldHighlightNetwork(network)) 378 flag |= FLAG_ASSOCIATED; 379 const gfx::ImageSkia icon = ash::network_icon::GetImageForNetwork( 380 network, ash::network_icon::ICON_TYPE_LIST); 381 menu_items_.push_back( 382 MenuItem(ui::MenuModel::TYPE_COMMAND, 383 label, icon, network->path(), flag)); 384} 385 386void MainMenuModel::AddMessageItem(const string16& msg) { 387 menu_items_.push_back(MenuItem( 388 ui::MenuModel::TYPE_COMMAND, msg, 389 gfx::ImageSkia(), std::string(), FLAG_DISABLED)); 390} 391 392void MainMenuModel::InitMenuItems(bool should_open_button_options) { 393 menu_items_.clear(); 394 395 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); 396 397 // Populate our MenuItems with the current list of networks. 398 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 399 string16 label; 400 401 // Ethernet 402 // Only display an ethernet icon if enabled, and an ethernet network exists. 403 bool ethernet_enabled = handler->IsTechnologyEnabled(flimflam::kTypeEthernet); 404 const NetworkState* ethernet_network = 405 handler->FirstNetworkByType(flimflam::kTypeEthernet); 406 if (ethernet_enabled && ethernet_network) { 407 bool ethernet_connecting = ethernet_network->IsConnectingState(); 408 if (ethernet_connecting) { 409 label = l10n_util::GetStringFUTF16( 410 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 411 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET), 412 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)); 413 } else { 414 label = l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); 415 } 416 int flag = FLAG_ETHERNET; 417 if (ShouldHighlightNetwork(ethernet_network)) 418 flag |= FLAG_ASSOCIATED; 419 const gfx::ImageSkia icon = ash::network_icon::GetImageForNetwork( 420 ethernet_network, ash::network_icon::ICON_TYPE_LIST); 421 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, 422 label, icon, std::string(), flag)); 423 } 424 425 // Get the list of all networks. 426 NetworkStateHandler::NetworkStateList network_list; 427 handler->GetNetworkList(&network_list); 428 429 // Cellular Networks 430 if (handler->IsTechnologyEnabled(flimflam::kTypeCellular)) { 431 // List Cellular networks. 432 for (NetworkStateHandler::NetworkStateList::const_iterator iter = 433 network_list.begin(); iter != network_list.end(); ++iter) { 434 const NetworkState* network = *iter; 435 if (network->type() != flimflam::kTypeCellular) 436 continue; 437 std::string activation_state = network->activation_state(); 438 439 // This is only used in the login screen; do not show unactivated 440 // networks. 441 if (activation_state != flimflam::kActivationStateActivated) 442 continue; 443 444 // Ampersand is a valid character in a network name, but menu2 uses it 445 // to mark "mnemonics" for keyboard shortcuts. http://crosbug.com/14697 446 std::string network_name = EscapeAmpersands(network->name()); 447 if (network->IsConnectingState()) { 448 label = l10n_util::GetStringFUTF16( 449 IDS_STATUSBAR_NETWORK_DEVICE_STATUS, 450 UTF8ToUTF16(network_name), 451 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING)); 452 } else { 453 label = UTF8ToUTF16(network_name); 454 } 455 456 int flag = FLAG_CELLULAR; 457 bool isActive = ShouldHighlightNetwork(network); 458 if (isActive) 459 flag |= FLAG_ASSOCIATED; 460 const gfx::ImageSkia icon = ash::network_icon::GetImageForNetwork( 461 network, ash::network_icon::ICON_TYPE_LIST); 462 menu_items_.push_back( 463 MenuItem(ui::MenuModel::TYPE_COMMAND, 464 label, icon, network->path(), flag)); 465 } 466 467 // For GSM add cellular network scan. 468 const DeviceState* cellular_device = 469 handler->GetDeviceStateByType(flimflam::kTypeCellular); 470 if (cellular_device && cellular_device->support_network_scan()) { 471 const gfx::ImageSkia icon = 472 ash::network_icon::GetImageForDisconnectedNetwork( 473 ash::network_icon::ICON_TYPE_LIST, flimflam::kTypeCellular); 474 menu_items_.push_back(MenuItem( 475 ui::MenuModel::TYPE_COMMAND, 476 l10n_util::GetStringUTF16( 477 IDS_OPTIONS_SETTINGS_OTHER_CELLULAR_NETWORKS), 478 icon, std::string(), FLAG_ADD_CELLULAR)); 479 } 480 } else { 481 int initializing_message_id = 482 ash::network_icon::GetCellularUninitializedMsg(); 483 if (initializing_message_id) { 484 // Initializing cellular modem... 485 AddMessageItem(l10n_util::GetStringUTF16(initializing_message_id)); 486 } 487 } 488 489 // Wimax Networks 490 if (handler->IsTechnologyEnabled(flimflam::kTypeWimax)) { 491 // List Wimax networks. 492 for (NetworkStateHandler::NetworkStateList::const_iterator iter = 493 network_list.begin(); iter != network_list.end(); ++iter) { 494 const NetworkState* network = *iter; 495 if (network->type() != flimflam::kTypeWimax) 496 continue; 497 AddWirelessNetworkMenuItem(network, FLAG_WIMAX); 498 } 499 } 500 501 // Wifi Networks 502 if (handler->IsTechnologyEnabled(flimflam::kTypeWifi)) { 503 // List Wifi networks. 504 int scanning_msg = handler->GetScanningByType(flimflam::kTypeWifi) ? 505 IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE : 0; 506 for (NetworkStateHandler::NetworkStateList::const_iterator iter = 507 network_list.begin(); iter != network_list.end(); ++iter) { 508 const NetworkState* network = *iter; 509 if (network->type() != flimflam::kTypeWifi) 510 continue; 511 // Add 'Searching for Wi-Fi networks...' after connected networks. 512 if (scanning_msg && !network->IsConnectedState()) { 513 AddMessageItem(l10n_util::GetStringUTF16(scanning_msg)); 514 scanning_msg = 0; 515 } 516 AddWirelessNetworkMenuItem(network, FLAG_WIFI); 517 } 518 if (scanning_msg) 519 AddMessageItem(l10n_util::GetStringUTF16(scanning_msg)); 520 const gfx::ImageSkia icon = 521 ash::network_icon::GetImageForConnectedNetwork( 522 ash::network_icon::ICON_TYPE_LIST, flimflam::kTypeWifi); 523 menu_items_.push_back(MenuItem( 524 ui::MenuModel::TYPE_COMMAND, 525 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_WIFI_NETWORKS), 526 icon, std::string(), FLAG_ADD_WIFI)); 527 } 528 529 if (menu_items_.empty()) { 530 // No networks available (and not initializing cellular or wifi scanning) 531 AddMessageItem(l10n_util::GetStringFUTF16( 532 IDS_STATUSBAR_NETWORK_MENU_ITEM_INDENT, 533 l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE))); 534 } 535 536 // Enable / Disable Technology 537 NetworkStateHandler::TechnologyState wifi_state = 538 handler->GetTechnologyState(flimflam::kTypeWifi); 539 bool wifi_available = 540 wifi_state != NetworkStateHandler::TECHNOLOGY_UNAVAILABLE; 541 bool wifi_enabled = wifi_state == NetworkStateHandler::TECHNOLOGY_ENABLED; 542 543 NetworkStateHandler::TechnologyState mobile_state = 544 handler->GetTechnologyState(NetworkStateHandler::kMatchTypeMobile); 545 bool mobile_available = 546 mobile_state != NetworkStateHandler::TECHNOLOGY_UNAVAILABLE; 547 bool mobile_enabled = mobile_state == NetworkStateHandler::TECHNOLOGY_ENABLED; 548 549 // Do not show disable wifi or cellular during oobe. 550 bool show_toggle_wifi = wifi_available && 551 (should_open_button_options || !wifi_enabled); 552 bool show_toggle_mobile = mobile_available && 553 (should_open_button_options || !mobile_enabled); 554 555 if (show_toggle_wifi || show_toggle_mobile) { 556 menu_items_.push_back(MenuItem()); // Separator 557 558 if (show_toggle_wifi) { 559 int id = wifi_enabled ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE : 560 IDS_STATUSBAR_NETWORK_DEVICE_ENABLE; 561 label = l10n_util::GetStringFUTF16(id, 562 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_WIFI)); 563 int flag = FLAG_TOGGLE_WIFI; 564 if (wifi_state == NetworkStateHandler::TECHNOLOGY_ENABLING) 565 flag |= FLAG_DISABLED; 566 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 567 gfx::ImageSkia(), std::string(), flag)); 568 } 569 570 if (show_toggle_mobile) { 571 const DeviceState* mobile_device = 572 handler->GetDeviceStateByType(NetworkStateHandler::kMatchTypeMobile); 573 bool is_locked = mobile_device && !mobile_device->sim_lock_type().empty(); 574 int id = (mobile_enabled && !is_locked) 575 ? IDS_STATUSBAR_NETWORK_DEVICE_DISABLE 576 : IDS_STATUSBAR_NETWORK_DEVICE_ENABLE; 577 label = l10n_util::GetStringFUTF16(id, 578 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CELLULAR)); 579 gfx::ImageSkia icon; 580 if (is_locked) 581 icon = *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_SECURE_DARK); 582 int flag = FLAG_TOGGLE_MOBILE; 583 if (mobile_state == NetworkStateHandler::TECHNOLOGY_ENABLING) 584 flag |= FLAG_DISABLED; 585 menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label, 586 icon, std::string(), flag)); 587 } 588 } 589 590 // Additional links like: 591 // * IP Address on active interface; 592 // * Hardware addresses for wifi and ethernet. 593 more_menu_model_->InitMenuItems(should_open_button_options); 594 if (!more_menu_model_->menu_items().empty()) { 595 menu_items_.push_back(MenuItem()); // Separator 596 menu_items_.push_back(MenuItem( 597 ui::MenuModel::TYPE_SUBMENU, 598 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_MORE), 599 gfx::ImageSkia(), more_menu_model_.get(), FLAG_NONE)); 600 } 601} 602 603int MainMenuModel::GetCommandIdAt(int index) const { 604 return index + kMainIndexMask; 605} 606 607//////////////////////////////////////////////////////////////////////////////// 608// MoreMenuModel 609 610void MoreMenuModel::InitMenuItems(bool should_open_button_options) { 611 menu_items_.clear(); 612 MenuItemVector link_items; 613 MenuItemVector address_items; 614 615 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); 616 const NetworkState* default_network = handler->DefaultNetwork(); 617 618 int message_id = -1; 619 if (default_network) 620 message_id = IDS_STATUSBAR_NETWORK_OPEN_PROXY_SETTINGS_DIALOG; 621 if (message_id != -1) { 622 link_items.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, 623 l10n_util::GetStringUTF16(message_id), 624 gfx::ImageSkia(), 625 std::string(), 626 FLAG_OPTIONS)); 627 } 628 629 if (default_network) { 630 std::string ip_address = default_network->ip_address(); 631 if (!ip_address.empty()) { 632 address_items.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, 633 ASCIIToUTF16(ip_address), gfx::ImageSkia(), std::string(), 634 FLAG_DISABLED)); 635 } 636 } 637 638 std::string ethernet_address = 639 handler->FormattedHardwareAddressForType(flimflam::kTypeEthernet); 640 if (!ethernet_address.empty()) { 641 std::string label = l10n_util::GetStringUTF8( 642 IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET) + " " + ethernet_address; 643 address_items.push_back(MenuItem( 644 ui::MenuModel::TYPE_COMMAND, 645 UTF8ToUTF16(label), gfx::ImageSkia(), std::string(), FLAG_DISABLED)); 646 } 647 648 std::string wifi_address = 649 handler->FormattedHardwareAddressForType(flimflam::kTypeWifi); 650 if (!wifi_address.empty()) { 651 std::string label = l10n_util::GetStringUTF8( 652 IDS_STATUSBAR_NETWORK_DEVICE_WIFI) + " " + wifi_address; 653 address_items.push_back(MenuItem( 654 ui::MenuModel::TYPE_COMMAND, 655 UTF8ToUTF16(label), gfx::ImageSkia(), std::string(), FLAG_DISABLED)); 656 } 657 658 menu_items_ = link_items; 659 if (!menu_items_.empty() && address_items.size() > 1) 660 menu_items_.push_back(MenuItem()); // Separator 661 menu_items_.insert(menu_items_.end(), 662 address_items.begin(), address_items.end()); 663} 664 665int MoreMenuModel::GetCommandIdAt(int index) const { 666 return index + kMoreIndexMask; 667} 668 669//////////////////////////////////////////////////////////////////////////////// 670// NetworkMenu 671 672NetworkMenu::NetworkMenu(Delegate* delegate) 673 : delegate_(delegate), 674 refreshing_menu_(false), 675 weak_pointer_factory_(this) { 676 main_menu_model_.reset(new MainMenuModel(weak_pointer_factory_.GetWeakPtr())); 677} 678 679NetworkMenu::~NetworkMenu() { 680} 681 682ui::MenuModel* NetworkMenu::GetMenuModel() { 683 return main_menu_model_.get(); 684} 685 686void NetworkMenu::UpdateMenu() { 687 refreshing_menu_ = true; 688 main_menu_model_->InitMenuItems(delegate_->ShouldOpenButtonOptions()); 689 refreshing_menu_ = false; 690} 691 692} // namespace chromeos 693