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/ui/webui/chromeos/login/network_dropdown.h" 6 7 #include <string> 8 9 #include "ash/system/chromeos/network/network_icon.h" 10 #include "ash/system/chromeos/network/network_icon_animation.h" 11 #include "base/time/time.h" 12 #include "base/values.h" 13 #include "chrome/browser/chromeos/login/ui/login_display_host.h" 14 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 15 #include "chromeos/network/network_state_handler.h" 16 #include "content/public/browser/web_ui.h" 17 #include "ui/base/models/menu_model.h" 18 #include "ui/base/webui/web_ui_util.h" 19 #include "ui/gfx/font_list.h" 20 #include "ui/gfx/image/image.h" 21 #include "ui/gfx/image/image_skia.h" 22 23 namespace { 24 25 // Timeout between consecutive requests to network library for network 26 // scan. 27 const int kNetworkScanIntervalSecs = 60; 28 29 } // namespace 30 31 namespace chromeos { 32 33 // WebUI specific implementation of the NetworkMenu class. 34 class NetworkMenuWebUI : public NetworkMenu { 35 public: 36 NetworkMenuWebUI(NetworkMenu::Delegate* delegate, content::WebUI* web_ui); 37 38 // NetworkMenu override: 39 virtual void UpdateMenu() OVERRIDE; 40 41 // Called when item with command |id| is chosen. 42 void OnItemChosen(int id); 43 44 private: 45 // Converts menu model into the ListValue, ready for passing to WebUI. 46 base::ListValue* ConvertMenuModel(ui::MenuModel* model); 47 48 // WebUI where network menu is located. 49 content::WebUI* web_ui_; 50 51 DISALLOW_COPY_AND_ASSIGN(NetworkMenuWebUI); 52 }; 53 54 // NetworkMenuWebUI ------------------------------------------------------------ 55 56 NetworkMenuWebUI::NetworkMenuWebUI(NetworkMenu::Delegate* delegate, 57 content::WebUI* web_ui) 58 : NetworkMenu(delegate), 59 web_ui_(web_ui) { 60 } 61 62 void NetworkMenuWebUI::UpdateMenu() { 63 NetworkMenu::UpdateMenu(); 64 if (web_ui_) { 65 scoped_ptr<base::ListValue> list(ConvertMenuModel(GetMenuModel())); 66 web_ui_->CallJavascriptFunction("cr.ui.DropDown.updateNetworks", *list); 67 } 68 } 69 70 void NetworkMenuWebUI::OnItemChosen(int id) { 71 int index; 72 ui::MenuModel* model = GetMenuModel(); 73 if (!ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) 74 return; 75 model->ActivatedAt(index); 76 } 77 78 base::ListValue* NetworkMenuWebUI::ConvertMenuModel(ui::MenuModel* model) { 79 base::ListValue* list = new base::ListValue(); 80 for (int i = 0; i < model->GetItemCount(); ++i) { 81 ui::MenuModel::ItemType type = model->GetTypeAt(i); 82 int id; 83 if (type == ui::MenuModel::TYPE_SEPARATOR) 84 id = -2; 85 else 86 id = model->GetCommandIdAt(i); 87 base::DictionaryValue* item = new base::DictionaryValue(); 88 item->SetInteger("id", id); 89 item->SetString("label", model->GetLabelAt(i)); 90 gfx::Image icon; 91 if (model->GetIconAt(i, &icon)) { 92 SkBitmap icon_bitmap = icon.ToImageSkia()->GetRepresentation( 93 web_ui_->GetDeviceScaleFactor()).sk_bitmap(); 94 item->SetString("icon", webui::GetBitmapDataUrl(icon_bitmap)); 95 } 96 if (id >= 0) { 97 item->SetBoolean("enabled", model->IsEnabledAt(i)); 98 const gfx::FontList* font_list = model->GetLabelFontListAt(i); 99 if (font_list) 100 item->SetBoolean("bold", font_list->GetFontStyle() == gfx::Font::BOLD); 101 } 102 if (type == ui::MenuModel::TYPE_SUBMENU) 103 item->Set("sub", ConvertMenuModel(model->GetSubmenuModelAt(i))); 104 list->Append(item); 105 } 106 return list; 107 } 108 109 // NetworkDropdown ------------------------------------------------------------- 110 111 NetworkDropdown::NetworkDropdown(Actor* actor, 112 content::WebUI* web_ui, 113 bool oobe) 114 : actor_(actor), 115 web_ui_(web_ui), 116 oobe_(oobe) { 117 DCHECK(actor_); 118 network_menu_.reset(new NetworkMenuWebUI(this, web_ui)); 119 DCHECK(NetworkHandler::IsInitialized()); 120 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); 121 handler->RequestScan(); 122 handler->AddObserver(this, FROM_HERE); 123 Refresh(); 124 network_scan_timer_.Start( 125 FROM_HERE, 126 base::TimeDelta::FromSeconds(kNetworkScanIntervalSecs), 127 this, &NetworkDropdown::RequestNetworkScan); 128 } 129 130 NetworkDropdown::~NetworkDropdown() { 131 ash::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); 132 if (NetworkHandler::IsInitialized()) { 133 NetworkHandler::Get()->network_state_handler()->RemoveObserver( 134 this, FROM_HERE); 135 } 136 } 137 138 void NetworkDropdown::OnItemChosen(int id) { 139 network_menu_->OnItemChosen(id); 140 } 141 142 gfx::NativeWindow NetworkDropdown::GetNativeWindow() const { 143 return LoginDisplayHostImpl::default_host()->GetNativeWindow(); 144 } 145 146 void NetworkDropdown::OpenButtonOptions() { 147 LoginDisplayHostImpl::default_host()->OpenProxySettings(); 148 } 149 150 bool NetworkDropdown::ShouldOpenButtonOptions() const { 151 return !oobe_; 152 } 153 154 void NetworkDropdown::OnConnectToNetworkRequested( 155 const std::string& service_path) { 156 actor_->OnConnectToNetworkRequested(service_path); 157 } 158 159 void NetworkDropdown::DefaultNetworkChanged(const NetworkState* network) { 160 Refresh(); 161 } 162 163 void NetworkDropdown::NetworkConnectionStateChanged( 164 const NetworkState* network) { 165 Refresh(); 166 } 167 168 void NetworkDropdown::NetworkListChanged() { 169 Refresh(); 170 } 171 172 void NetworkDropdown::NetworkIconChanged() { 173 SetNetworkIconAndText(); 174 } 175 176 void NetworkDropdown::Refresh() { 177 SetNetworkIconAndText(); 178 network_menu_->UpdateMenu(); 179 } 180 181 void NetworkDropdown::SetNetworkIconAndText() { 182 base::string16 text; 183 gfx::ImageSkia icon_image; 184 bool animating = false; 185 ash::network_icon::GetDefaultNetworkImageAndLabel( 186 ash::network_icon::ICON_TYPE_LIST, &icon_image, &text, &animating); 187 if (animating) { 188 ash::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); 189 } else { 190 ash::network_icon::NetworkIconAnimation::GetInstance()-> 191 RemoveObserver(this); 192 } 193 SkBitmap icon_bitmap = icon_image.GetRepresentation( 194 web_ui_->GetDeviceScaleFactor()).sk_bitmap(); 195 std::string icon_str; 196 if (!icon_image.isNull()) 197 icon_str = webui::GetBitmapDataUrl(icon_bitmap); 198 base::StringValue title(text); 199 base::StringValue icon(icon_str); 200 web_ui_->CallJavascriptFunction("cr.ui.DropDown.updateNetworkTitle", 201 title, icon); 202 } 203 204 void NetworkDropdown::RequestNetworkScan() { 205 NetworkHandler::Get()->network_state_handler()->RequestScan(); 206 Refresh(); 207 } 208 209 } // namespace chromeos 210