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#ifndef CHROME_BROWSER_CHROMEOS_STATUS_NETWORK_MENU_H_
6#define CHROME_BROWSER_CHROMEOS_STATUS_NETWORK_MENU_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "chrome/browser/chromeos/options/network_config_view.h"
13#include "third_party/skia/include/core/SkBitmap.h"
14#include "ui/base/models/menu_model.h"
15#include "ui/gfx/native_widget_types.h"
16#include "views/controls/menu/view_menu_delegate.h"
17
18namespace gfx {
19class Canvas;
20}
21
22namespace views {
23class Menu2;
24}
25
26namespace chromeos {
27
28class NetworkMenu;
29
30class NetworkMenuModel : public ui::MenuModel {
31 public:
32  struct NetworkInfo {
33    NetworkInfo() :
34        need_passphrase(false), remembered(true), auto_connect(true) {}
35    // "ethernet" | "wifi" | "cellular" | "other".
36    std::string network_type;
37    // "connected" | "connecting" | "disconnected" | "error".
38    std::string status;
39    // status message or error message, empty if unknown status.
40    std::string message;
41    // IP address (if network is active, empty otherwise)
42    std::string ip_address;
43    // Remembered passphrase.
44    std::string passphrase;
45    // true if the network requires a passphrase.
46    bool need_passphrase;
47    // true if the network is currently remembered.
48    bool remembered;
49    // true if the network is auto connect (meaningful for Wifi only).
50    bool auto_connect;
51  };
52
53  explicit NetworkMenuModel(NetworkMenu* owner) : owner_(owner) {}
54  virtual ~NetworkMenuModel() {}
55
56  // Connect or reconnect to the network at |index|.
57  // If remember >= 0, set the favorite state of the network.
58  // Returns true if a connect occurred (e.g. menu should be closed).
59  bool ConnectToNetworkAt(int index,
60                          const std::string& passphrase,
61                          const std::string& ssid,
62                          int remember) const;
63
64  // Called by NetworkMenu::RunMenu to initialize list of menu items.
65  virtual void InitMenuItems(bool is_browser_mode,
66                             bool should_open_button_options) = 0;
67
68  // ui::MenuModel implementation.
69  virtual bool HasIcons() const  { return true; }
70  virtual int GetItemCount() const;
71  virtual ui::MenuModel::ItemType GetTypeAt(int index) const;
72  virtual int GetCommandIdAt(int index) const { return index; }
73  virtual string16 GetLabelAt(int index) const;
74  virtual bool IsItemDynamicAt(int index) const { return true; }
75  virtual const gfx::Font* GetLabelFontAt(int index) const;
76  virtual bool GetAcceleratorAt(int index,
77      ui::Accelerator* accelerator) const { return false; }
78  virtual bool IsItemCheckedAt(int index) const;
79  virtual int GetGroupIdAt(int index) const { return 0; }
80  virtual bool GetIconAt(int index, SkBitmap* icon);
81  virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const {
82    return NULL;
83  }
84  virtual bool IsEnabledAt(int index) const;
85  virtual ui::MenuModel* GetSubmenuModelAt(int index) const;
86  virtual void HighlightChangedTo(int index) {}
87  virtual void ActivatedAt(int index);
88  virtual void MenuWillShow() {}
89  virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) {}
90
91 protected:
92  enum MenuItemFlags {
93    FLAG_NONE              = 0,
94    FLAG_DISABLED          = 1 << 0,
95    FLAG_TOGGLE_ETHERNET   = 1 << 1,
96    FLAG_TOGGLE_WIFI       = 1 << 2,
97    FLAG_TOGGLE_CELLULAR   = 1 << 3,
98    FLAG_TOGGLE_OFFLINE    = 1 << 4,
99    FLAG_ASSOCIATED        = 1 << 5,
100    FLAG_ETHERNET          = 1 << 6,
101    FLAG_WIFI              = 1 << 7,
102    FLAG_CELLULAR          = 1 << 8,
103    FLAG_OPTIONS           = 1 << 9,
104    FLAG_ADD_WIFI          = 1 << 10,
105    FLAG_ADD_CELLULAR      = 1 << 11,
106    FLAG_VPN               = 1 << 12,
107    FLAG_ADD_VPN           = 1 << 13,
108    FLAG_DISCONNECT_VPN    = 1 << 14,
109    FLAG_VIEW_ACCOUNT      = 1 << 15,
110  };
111
112  struct MenuItem {
113    MenuItem()
114        : type(ui::MenuModel::TYPE_SEPARATOR),
115          sub_menu_model(NULL),
116          flags(0) {}
117    MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon,
118             const std::string& service_path, int flags)
119        : type(type),
120          label(label),
121          icon(icon),
122          service_path(service_path),
123          sub_menu_model(NULL),
124          flags(flags) {}
125    MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon,
126             NetworkMenuModel* sub_menu_model, int flags)
127        : type(type),
128          label(label),
129          icon(icon),
130          sub_menu_model(sub_menu_model),
131          flags(flags) {}
132
133    ui::MenuModel::ItemType type;
134    string16 label;
135    SkBitmap icon;
136    std::string service_path;
137    NetworkMenuModel* sub_menu_model;  // Weak.
138    int flags;
139  };
140  typedef std::vector<MenuItem> MenuItemVector;
141
142  // Our menu items.
143  MenuItemVector menu_items_;
144
145  NetworkMenu* owner_;  // Weak pointer to NetworkMenu that owns this MenuModel.
146
147  // Top up URL of the current carrier on empty string if there's none.
148  std::string top_up_url_;
149
150  // Carrier ID which top up URL is initialized for.
151  // Used to update top up URL only when cellular carrier has changed.
152  std::string carrier_id_;
153
154 private:
155  // Show a NetworkConfigView modal dialog instance.
156  void ShowNetworkConfigView(NetworkConfigView* view) const;
157
158  void ActivateCellular(const CellularNetwork* cellular) const;
159  void ShowOther(ConnectionType type) const;
160  void ShowOtherCellular() const;
161
162  DISALLOW_COPY_AND_ASSIGN(NetworkMenuModel);
163};
164
165// Menu for network menu button in the status area/welcome screen.
166// This class will populating the menu with the list of networks.
167// It will also handle connecting to another wifi/cellular network.
168//
169// The network menu looks like this:
170//
171// <icon>  Ethernet
172// <icon>  Wifi Network A
173// <icon>  Wifi Network B
174// <icon>  Wifi Network C
175// <icon>  Cellular Network A
176// <icon>  Cellular Network B
177// <icon>  Cellular Network C
178// <icon>  Other...
179// <icon>  Private networks ->
180//         <icon>  Virtual Network A
181//         <icon>  Virtual Network B
182//         ----------------------------------
183//                 Add private network...
184//                 Disconnect private network
185// --------------------------------
186//         Disable Wifi
187//         Disable Celluar
188// --------------------------------
189//         <IP Address>
190//         Network settings...
191//
192// <icon> will show the strength of the wifi/cellular networks.
193// The label will be BOLD if the network is currently connected.
194class NetworkMenu : public views::ViewMenuDelegate {
195 public:
196  NetworkMenu();
197  virtual ~NetworkMenu();
198
199  void SetFirstLevelMenuWidth(int width);
200
201  // Cancels the active menu.
202  void CancelMenu();
203
204  virtual bool IsBrowserMode() const = 0;
205
206  // The following methods returns pointer to a shared instance of the SkBitmap.
207  // This shared bitmap is owned by the resource bundle and should not be freed.
208
209  // Returns the Icon for a network strength for a WifiNetwork |wifi|.
210  // |black| is used to specify whether to return a black icon for display
211  // on a light background or a white icon for display on a dark background.
212  // Expected to never return NULL.
213  static const SkBitmap* IconForNetworkStrength(const WifiNetwork* wifi,
214                                                bool black);
215  // Returns the Icon for a network strength for CellularNetwork |cellular|.
216  // |black| is used to specify whether to return a black icon for display
217  // on a light background or a white icon for display on a dark background.
218  // Expected to never return NULL.
219  static const SkBitmap* IconForNetworkStrength(const CellularNetwork* cellular,
220                                                bool black);
221  // Returns the Icon for animating network connecting.
222  // |animation_value| is the value from Animation.GetCurrentValue()
223  // |black| is used to specify whether to return a black icon for display
224  // on a light background or a white icon for display on a dark background.
225  // Expected to never return NULL.
226  static const SkBitmap* IconForNetworkConnecting(double animation_value,
227                                                  bool black);
228
229  // Returns the Badge for a given network technology.
230  // This returns different colored symbols depending on cellular data left.
231  // Returns NULL if not badge is needed.
232  static const SkBitmap* BadgeForNetworkTechnology(
233      const CellularNetwork* cellular);
234  // Returns the Badge for a given network roaming status.
235  // This returns "R" badge if network is in roaming state, otherwise
236  // returns NULL. Badge is supposed to be shown on top right of the icon.
237  static const SkBitmap* BadgeForRoamingStatus(const CellularNetwork* cellular);
238  // Returns the badge for the given network if it's active with vpn.
239  // If |network| is not null, will check if it's the active network.
240  // If |network| is null or if |network| is the active one, the yellow lock
241  // badge will be returned, otherwise returns null.
242  // Badge is supposed to be shown on in bottom left corner of the icon.
243  static const SkBitmap* BadgeForPrivateNetworkStatus(const Network* network);
244
245  // This method will convert the |icon| bitmap to the correct size for display.
246  // |icon| must be non-NULL.
247  // If |badge| icon is not NULL, it will be drawn on top of the icon in
248  // the bottom-right corner.
249  static SkBitmap IconForDisplay(const SkBitmap* icon, const SkBitmap* badge);
250  // This method will convert the |icon| bitmap to the correct size for display.
251  // |icon| must be non-NULL.
252  // If one of the |bottom_right_badge| or |top_left_badge| or
253  // |bottom_left_badge| icons are not NULL, they will be drawn on top of the
254  // icon.
255  static SkBitmap IconForDisplay(const SkBitmap* icon,
256                                 const SkBitmap* bottom_right_badge,
257                                 const SkBitmap* top_left_badge,
258                                 const SkBitmap* bottom_left_badge);
259
260 protected:
261  virtual gfx::NativeWindow GetNativeWindow() const = 0;
262  virtual void OpenButtonOptions() = 0;
263  virtual bool ShouldOpenButtonOptions() const = 0;
264
265  // Notify subclasses that connection to |network| was initiated.
266  virtual void OnConnectNetwork(const Network* network,
267                                SkBitmap selected_icon_) {}
268
269  // Shows network details in Web UI options window.
270  void ShowTabbedNetworkSettings(const Network* network) const;
271
272  // Update the menu (e.g. when the network list or status has changed).
273  void UpdateMenu();
274
275 private:
276  friend class NetworkMenuModel;
277
278  // views::ViewMenuDelegate implementation.
279  virtual void RunMenu(views::View* source, const gfx::Point& pt);
280
281  // Set to true if we are currently refreshing the menu.
282  bool refreshing_menu_;
283
284  // The number of bars images for representing network strength.
285  static const int kNumBarsImages;
286
287  // Bars image resources.
288  static const int kBarsImages[];
289  static const int kBarsImagesBlack[];
290  static const int kBarsImagesOrange[];
291  // TODO(chocobo): Add this back when we decide to do colored bars again.
292  // static const int kBarsImagesVLowData[];
293
294  // Animation images. These are created lazily.
295  static SkBitmap kAnimatingImages[];
296  static SkBitmap kAnimatingImagesBlack[];
297
298  // The network menu.
299  scoped_ptr<views::Menu2> network_menu_;
300
301  scoped_ptr<NetworkMenuModel> main_menu_model_;
302
303  // Holds minimum width or -1 if it wasn't set up.
304  int min_width_;
305
306  // If true, call into the settings UI for network configuration dialogs.
307  bool use_settings_ui_;
308
309  DISALLOW_COPY_AND_ASSIGN(NetworkMenu);
310};
311
312}  // namespace chromeos
313
314#endif  // CHROME_BROWSER_CHROMEOS_STATUS_NETWORK_MENU_H_
315