Home | History | Annotate | Download | only in login
      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/login_display_host.h"
     14 #include "chrome/browser/chromeos/login/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/gfx/font.h"
     19 #include "ui/gfx/image/image.h"
     20 #include "ui/gfx/image/image_skia.h"
     21 #include "ui/webui/web_ui_util.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::Font* font = model->GetLabelFontAt(i);
     99       if (font) {
    100         item->SetBoolean("bold", font->GetStyle() == gfx::Font::BOLD);
    101       }
    102     }
    103     if (type == ui::MenuModel::TYPE_SUBMENU)
    104       item->Set("sub", ConvertMenuModel(model->GetSubmenuModelAt(i)));
    105     list->Append(item);
    106   }
    107   return list;
    108 }
    109 
    110 // NetworkDropdown -------------------------------------------------------------
    111 
    112 NetworkDropdown::NetworkDropdown(Actor* actor,
    113                                  content::WebUI* web_ui,
    114                                  bool oobe)
    115     : actor_(actor),
    116       web_ui_(web_ui),
    117       oobe_(oobe) {
    118   DCHECK(actor_);
    119   network_menu_.reset(new NetworkMenuWebUI(this, web_ui));
    120   DCHECK(NetworkHandler::IsInitialized());
    121   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
    122   handler->RequestScan();
    123   handler->AddObserver(this, FROM_HERE);
    124   Refresh();
    125   network_scan_timer_.Start(
    126       FROM_HERE,
    127       base::TimeDelta::FromSeconds(kNetworkScanIntervalSecs),
    128       this, &NetworkDropdown::RequestNetworkScan);
    129 }
    130 
    131 NetworkDropdown::~NetworkDropdown() {
    132   ash::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
    133   if (NetworkHandler::IsInitialized()) {
    134     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
    135         this, FROM_HERE);
    136   }
    137 }
    138 
    139 void NetworkDropdown::OnItemChosen(int id) {
    140   network_menu_->OnItemChosen(id);
    141 }
    142 
    143 gfx::NativeWindow NetworkDropdown::GetNativeWindow() const {
    144   return LoginDisplayHostImpl::default_host()->GetNativeWindow();
    145 }
    146 
    147 void NetworkDropdown::OpenButtonOptions() {
    148   LoginDisplayHostImpl::default_host()->OpenProxySettings();
    149 }
    150 
    151 bool NetworkDropdown::ShouldOpenButtonOptions() const {
    152   return !oobe_;
    153 }
    154 
    155 void NetworkDropdown::OnConnectToNetworkRequested(
    156     const std::string& service_path) {
    157   actor_->OnConnectToNetworkRequested(service_path);
    158 }
    159 
    160 void NetworkDropdown::DefaultNetworkChanged(const NetworkState* network) {
    161   Refresh();
    162 }
    163 
    164 void NetworkDropdown::NetworkConnectionStateChanged(
    165     const NetworkState* network) {
    166   Refresh();
    167 }
    168 
    169 void NetworkDropdown::NetworkListChanged() {
    170   Refresh();
    171 }
    172 
    173 void NetworkDropdown::NetworkIconChanged() {
    174   SetNetworkIconAndText();
    175 }
    176 
    177 void NetworkDropdown::Refresh() {
    178   SetNetworkIconAndText();
    179   network_menu_->UpdateMenu();
    180 }
    181 
    182 void NetworkDropdown::SetNetworkIconAndText() {
    183   string16 text;
    184   gfx::ImageSkia icon_image;
    185   bool animating = false;
    186   ash::network_icon::GetDefaultNetworkImageAndLabel(
    187       ash::network_icon::ICON_TYPE_LIST, &icon_image, &text, &animating);
    188   if (animating) {
    189     ash::network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
    190   } else {
    191     ash::network_icon::NetworkIconAnimation::GetInstance()->
    192         RemoveObserver(this);
    193   }
    194   SkBitmap icon_bitmap = icon_image.GetRepresentation(
    195       web_ui_->GetDeviceScaleFactor()).sk_bitmap();
    196   std::string icon_str;
    197   if (!icon_image.isNull())
    198     icon_str = webui::GetBitmapDataUrl(icon_bitmap);
    199   base::StringValue title(text);
    200   base::StringValue icon(icon_str);
    201   web_ui_->CallJavascriptFunction("cr.ui.DropDown.updateNetworkTitle",
    202                                   title, icon);
    203 }
    204 
    205 void NetworkDropdown::RequestNetworkScan() {
    206   NetworkHandler::Get()->network_state_handler()->RequestScan();
    207   Refresh();
    208 }
    209 
    210 }  // namespace chromeos
    211