diff options
Diffstat (limited to 'chrome/browser/chromeos')
-rw-r--r-- | chrome/browser/chromeos/clock_menu_button.cc | 97 | ||||
-rw-r--r-- | chrome/browser/chromeos/clock_menu_button.h | 59 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros_library.cc | 34 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros_library.h | 27 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros_network_library.cc | 142 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros_network_library.h | 101 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros_power_library.cc | 73 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros_power_library.h | 70 | ||||
-rw-r--r-- | chrome/browser/chromeos/network_menu_button.cc | 230 | ||||
-rw-r--r-- | chrome/browser/chromeos/network_menu_button.h | 78 | ||||
-rw-r--r-- | chrome/browser/chromeos/power_menu_button.cc | 126 | ||||
-rw-r--r-- | chrome/browser/chromeos/power_menu_button.h | 65 | ||||
-rw-r--r-- | chrome/browser/chromeos/settings_contents_view.cc | 181 | ||||
-rwxr-xr-x | chrome/browser/chromeos/status_area_view.cc | 177 | ||||
-rwxr-xr-x | chrome/browser/chromeos/status_area_view.h | 25 |
15 files changed, 953 insertions, 532 deletions
diff --git a/chrome/browser/chromeos/clock_menu_button.cc b/chrome/browser/chromeos/clock_menu_button.cc new file mode 100644 index 0000000..ee1b6ad --- /dev/null +++ b/chrome/browser/chromeos/clock_menu_button.cc @@ -0,0 +1,97 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/clock_menu_button.h" + +#include "app/gfx/canvas.h" +#include "app/gfx/font.h" +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/string_util.h" +#include "base/time.h" +#include "base/time_format.h" +#include "grit/generated_resources.h" + +// Amount of slop to add into the timer to make sure we're into the next minute +// when the timer goes off. +const int kTimerSlopSeconds = 1; + +ClockMenuButton::ClockMenuButton() + : MenuButton(NULL, std::wstring(), this, false), + clock_menu_(this) { + SetFont(ResourceBundle::GetSharedInstance().GetFont( + ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD)); + SetEnabledColor(SK_ColorWHITE); + SetShowHighlighted(false); + UpdateText(); +} + +void ClockMenuButton::SetNextTimer() { + // Try to set the timer to go off at the next change of the minute. We don't + // want to have the timer go off more than necessary since that will cause + // the CPU to wake up and consume power. + base::Time now = base::Time::Now(); + base::Time::Exploded exploded; + now.LocalExplode(&exploded); + + // Often this will be called at minute boundaries, and we'll actually want + // 60 seconds from now. + int seconds_left = 60 - exploded.second; + if (seconds_left == 0) + seconds_left = 60; + + // Make sure that the timer fires on the next minute. Without this, if it is + // called just a teeny bit early, then it will skip the next minute. + seconds_left += kTimerSlopSeconds; + + timer_.Start(base::TimeDelta::FromSeconds(seconds_left), this, + &ClockMenuButton::UpdateText); +} + +void ClockMenuButton::UpdateText() { + base::Time::Exploded now; + base::Time::Now().LocalExplode(&now); + int hour = now.hour % 12; + if (hour == 0) + hour = 12; + + std::wstring hour_str = IntToWString(hour); + std::wstring min_str = IntToWString(now.minute); + // Append a "0" before the minute if it's only a single digit. + if (now.minute < 10) + min_str = IntToWString(0) + min_str; + int msg = now.hour < 12 ? IDS_STATUSBAR_CLOCK_SHORT_TIME_AM : + IDS_STATUSBAR_CLOCK_SHORT_TIME_PM; + + std::wstring time_string = l10n_util::GetStringF(msg, hour_str, min_str); + + SetText(time_string); + SchedulePaint(); + SetNextTimer(); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClockMenuButton, views::Menu2Model implementation: + +int ClockMenuButton::GetItemCount() const { + return 1; +} + +views::Menu2Model::ItemType ClockMenuButton::GetTypeAt(int index) const { + return views::Menu2Model::TYPE_COMMAND; +} + +string16 ClockMenuButton::GetLabelAt(int index) const { + return WideToUTF16(base::TimeFormatFriendlyDate(base::Time::Now())); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClockMenuButton, views::ViewMenuDelegate implementation: + +void ClockMenuButton::RunMenu(views::View* source, const gfx::Point& pt, + gfx::NativeView hwnd) { + clock_menu_.Rebuild(); + clock_menu_.UpdateStates(); + clock_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); +} diff --git a/chrome/browser/chromeos/clock_menu_button.h b/chrome/browser/chromeos/clock_menu_button.h new file mode 100644 index 0000000..8fca16e --- /dev/null +++ b/chrome/browser/chromeos/clock_menu_button.h @@ -0,0 +1,59 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_CLOCK_MENU_BUTTON_H_ +#define CHROME_BROWSER_CHROMEOS_CLOCK_MENU_BUTTON_H_ + +#include "base/timer.h" +#include "views/controls/button/menu_button.h" +#include "views/controls/menu/menu_2.h" +#include "views/controls/menu/view_menu_delegate.h" + +// The clock menu button in the status area. +// This button shows the current time. +class ClockMenuButton : public views::MenuButton, + public views::ViewMenuDelegate, + public views::Menu2Model { + public: + ClockMenuButton(); + virtual ~ClockMenuButton() {} + + // views::Menu2Model implementation. + virtual bool HasIcons() const { return false; } + virtual int GetItemCount() const; + virtual views::Menu2Model::ItemType GetTypeAt(int index) const; + virtual int GetCommandIdAt(int index) const { return index; } + virtual string16 GetLabelAt(int index) const; + virtual bool IsLabelDynamicAt(int index) const { return true; } + virtual bool GetAcceleratorAt(int index, + views::Accelerator* accelerator) const { return false; } + virtual bool IsItemCheckedAt(int index) const { return false; } + virtual int GetGroupIdAt(int index) const { return 0; } + virtual bool GetIconAt(int index, SkBitmap* icon) const { return false; } + virtual bool IsEnabledAt(int index) const { return false; } + virtual Menu2Model* GetSubmenuModelAt(int index) const { return NULL; } + virtual void HighlightChangedTo(int index) {} + virtual void ActivatedAt(int index) {} + virtual void MenuWillShow() {} + + private: + // views::ViewMenuDelegate implementation. + virtual void RunMenu(views::View* source, const gfx::Point& pt, + gfx::NativeView hwnd); + + // Schedules the timer to fire at the next minute interval. + void SetNextTimer(); + + // Updates the time on the menu button and sets the next timer. + void UpdateText(); + + base::OneShotTimer<ClockMenuButton> timer_; + + // The clock menu. + views::Menu2 clock_menu_; + + DISALLOW_COPY_AND_ASSIGN(ClockMenuButton); +}; + +#endif // CHROME_BROWSER_CHROMEOS_CLOCK_MENU_BUTTON_H_ diff --git a/chrome/browser/chromeos/cros_library.cc b/chrome/browser/chromeos/cros_library.cc new file mode 100644 index 0000000..b248db3 --- /dev/null +++ b/chrome/browser/chromeos/cros_library.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/cros_library.h" + +#include <dlfcn.h> + +#include "base/file_path.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" +#include "third_party/cros/chromeos_cros_api.h" + +// static +bool CrosLibrary::loaded_ = false; + +// static +bool CrosLibrary::loaded() { + static bool initialized = false; + if (!initialized) { + FilePath path; + if (PathService::Get(chrome::FILE_CHROMEOS_API, &path)) + loaded_ = chromeos::LoadCros(path.value().c_str()); + + if (!loaded_) { + char* error = dlerror(); + if (error) + LOG(ERROR) << "Problem loading chromeos shared object: " << error; + } + initialized = true; + } + return loaded_; +} diff --git a/chrome/browser/chromeos/cros_library.h b/chrome/browser/chromeos/cros_library.h new file mode 100644 index 0000000..56d2b91 --- /dev/null +++ b/chrome/browser/chromeos/cros_library.h @@ -0,0 +1,27 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_CROS_LIBRARY_H_ +#define CHROME_BROWSER_CHROMEOS_CROS_LIBRARY_H_ + +#include "base/basictypes.h" + +// This class handles the loading of the ChromeOS shared library. +class CrosLibrary { + public: + // Returns true if the ChromeOS library was loaded. + // If this is the first time this method is called, + // we will attempt to load the ChromeOS shared library. + static bool loaded(); + + private: + CrosLibrary() {} + ~CrosLibrary() {} + + static bool loaded_; + + DISALLOW_COPY_AND_ASSIGN(CrosLibrary); +}; + +#endif // CHROME_BROWSER_CHROMEOS_CROS_LIBRARY_H_ diff --git a/chrome/browser/chromeos/cros_network_library.cc b/chrome/browser/chromeos/cros_network_library.cc new file mode 100644 index 0000000..0db1da7 --- /dev/null +++ b/chrome/browser/chromeos/cros_network_library.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/cros_network_library.h" + +#include <algorithm> + +#include "base/string_util.h" +#include "chrome/browser/chromeos/cros_library.h" + +CrosNetworkLibrary::CrosNetworkLibrary() + : ethernet_connected_(false), + wifi_connecting_(false), + wifi_strength_(0) { + if (CrosLibrary::loaded()) { + InitNetworkStatus(); + chromeos::MonitorNetworkStatus(&NetworkStatusChangedHandler, this); + } +} + +// static +CrosNetworkLibrary* CrosNetworkLibrary::Get() { + return Singleton<CrosNetworkLibrary>::get(); +} + +// static +bool CrosNetworkLibrary::loaded() { + return CrosLibrary::loaded(); +} + +void CrosNetworkLibrary::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void CrosNetworkLibrary::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +WifiNetworkVector CrosNetworkLibrary::GetWifiNetworks() { + WifiNetworkVector networks; + if (CrosLibrary::loaded()) { + chromeos::ServiceStatus* service_status = chromeos::GetAvailableNetworks(); + for (int i = 0; i < service_status->size; i++) { + const chromeos::ServiceInfo& service = service_status->services[i]; + if (service.type == chromeos::TYPE_WIFI) { + // Found a wifi network, add it to the list. + networks.push_back(WifiNetwork(service.ssid, service.needs_passphrase, + service.encryption, + service.signal_strength)); + } + } + chromeos::FreeServiceStatus(service_status); + } + + // Sort the list of wifi networks by ssid. + std::sort(networks.begin(), networks.end()); + + return networks; +} + +static const char* GetEncryptionString(chromeos::EncryptionType encryption) { + switch (encryption) { + case chromeos::NONE: + return "none"; + case chromeos::RSN: + return "rsn"; + case chromeos::WEP: + return "wep"; + case chromeos::WPA: + return "wpa"; + } + return "none"; +} + +void CrosNetworkLibrary::ConnectToWifiNetwork(WifiNetwork network, + const string16& password) { + bool ok = true; + if (CrosLibrary::loaded()) { + ok = chromeos::ConnectToWifiNetwork(network.ssid.c_str(), + password.empty() ? NULL : UTF16ToUTF8(password).c_str(), + GetEncryptionString(network.encryption)); + } + if (ok) { + // Notify all observers that connection has started. + wifi_ssid_ = network.ssid; + wifi_connecting_ = true; + wifi_strength_ = network.strength; + FOR_EACH_OBSERVER(Observer, observers_, NetworkChanged(this)); + } +} + +// static +void CrosNetworkLibrary::NetworkStatusChangedHandler(void* object, + const chromeos::ServiceInfo& service) { + CrosNetworkLibrary* network = static_cast<CrosNetworkLibrary*>(object); + network->ParseNetworkServiceInfo(service); + FOR_EACH_OBSERVER(Observer, network->observers_, NetworkChanged(network)); +} + +void CrosNetworkLibrary::ParseNetworkServiceInfo( + const chromeos::ServiceInfo& service) { + DLOG(INFO) << "Parse " << service.ssid << + " typ=" << service.type << + " sta=" << service.state << + " pas=" << service.needs_passphrase << + " enc=" << service.encryption << + " sig=" << service.signal_strength; + if (service.type == chromeos::TYPE_ETHERNET) { + // Get the ethernet status. + ethernet_connected_ = service.state == chromeos::STATE_READY; + } else if (service.type == chromeos::TYPE_WIFI) { + if (service.state == chromeos::STATE_READY) { + // Record the wifi network that is connected. + wifi_ssid_ = service.ssid; + wifi_connecting_ = false; + wifi_strength_ = service.signal_strength; + } else if (service.state == chromeos::STATE_ASSOCIATION || + service.state == chromeos::STATE_CONFIGURATION) { + // Record the wifi network that is connecting. + wifi_ssid_ = service.ssid; + wifi_connecting_ = true; + wifi_strength_ = service.signal_strength; + } else { + // A wifi network is disconnected. + // If it is the current connected (or connecting) wifi network, then + // we are currently disconnected from any wifi network. + if (service.ssid == wifi_ssid_) { + wifi_ssid_.clear(); + wifi_connecting_ = false; + wifi_strength_ = 0; + } + } + } +} + +void CrosNetworkLibrary::InitNetworkStatus() { + chromeos::ServiceStatus* service_status = chromeos::GetAvailableNetworks(); + for (int i = 0; i < service_status->size; i++) + ParseNetworkServiceInfo(service_status->services[i]); + chromeos::FreeServiceStatus(service_status); +} diff --git a/chrome/browser/chromeos/cros_network_library.h b/chrome/browser/chromeos/cros_network_library.h new file mode 100644 index 0000000..b73e1e6 --- /dev/null +++ b/chrome/browser/chromeos/cros_network_library.h @@ -0,0 +1,101 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_ +#define CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_ + +#include <string> +#include <vector> + +#include "base/observer_list.h" +#include "base/singleton.h" +#include "base/string16.h" +#include "third_party/cros/chromeos_network.h" + +struct WifiNetwork { + WifiNetwork() : encrypted(false), encryption(chromeos::NONE), strength(0) {} + WifiNetwork(const std::string& ssid, bool encrypted, + chromeos::EncryptionType encryption, int strength) + : ssid(ssid), + encrypted(encrypted), + encryption(encryption), + strength(strength) { } + + // WifiNetworks are sorted by ssids. + bool operator< (const WifiNetwork& other) const { + return ssid < other.ssid; + } + + std::string ssid; + bool encrypted; + chromeos::EncryptionType encryption; + int strength; +}; +typedef std::vector<WifiNetwork> WifiNetworkVector; + +// This class handles the interaction with the ChromeOS network library APIs. +// Classes can add themselves as observers. Users can get an instance of this +// library class like this: CrosNetworkLibrary::Get() +class CrosNetworkLibrary { + public: + class Observer { + public: + virtual void NetworkChanged(CrosNetworkLibrary* obj) = 0; + }; + + // This gets the singleton CrosNetworkLibrary + static CrosNetworkLibrary* Get(); + + // Returns true if the ChromeOS library was loaded. + static bool loaded(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + bool ethernet_connected() const { return ethernet_connected_; } + const std::string& wifi_ssid() const { return wifi_ssid_; } + bool wifi_connecting() const { return wifi_connecting_; } + int wifi_strength() const { return wifi_strength_; } + + // Returns the current list of wifi networks. + WifiNetworkVector GetWifiNetworks(); + + // Connect to the specified wireless network with password. + void ConnectToWifiNetwork(WifiNetwork network, const string16& password); + + private: + friend struct DefaultSingletonTraits<CrosNetworkLibrary>; + + CrosNetworkLibrary(); + ~CrosNetworkLibrary() {} + + // This method is called when there's a change in network status. + // This will notify all the Observers. + static void NetworkStatusChangedHandler(void* object, + const chromeos::ServiceInfo& service); + + // Parse a ServiceInfo objects and update our status. + void ParseNetworkServiceInfo(const chromeos::ServiceInfo& service); + + // Initialize the network status on startup. + void InitNetworkStatus(); + + ObserverList<Observer> observers_; + + // Whether or not we are connected to the ethernet line. + bool ethernet_connected_; + + // The current connected (or connecting) wireless ssid. Empty if none. + std::string wifi_ssid_; + + // Whether or not we are connecting right now. + bool wifi_connecting_; + + // The strength of the currently connected ssid. + int wifi_strength_; + + DISALLOW_COPY_AND_ASSIGN(CrosNetworkLibrary); +}; + +#endif // CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_ diff --git a/chrome/browser/chromeos/cros_power_library.cc b/chrome/browser/chromeos/cros_power_library.cc new file mode 100644 index 0000000..ed17264 --- /dev/null +++ b/chrome/browser/chromeos/cros_power_library.cc @@ -0,0 +1,73 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/cros_power_library.h" + +#include "base/string_util.h" +#include "chrome/browser/chromeos/cros_library.h" + +CrosPowerLibrary::CrosPowerLibrary() { + if (CrosLibrary::loaded()) { + power_status_connection_ = chromeos::MonitorPowerStatus( + &PowerStatusChangedHandler, this); + } +} + +CrosPowerLibrary::~CrosPowerLibrary() { + if (CrosLibrary::loaded()) + chromeos::DisconnectPowerStatus(power_status_connection_); +} + +// static +CrosPowerLibrary* CrosPowerLibrary::Get() { + return Singleton<CrosPowerLibrary>::get(); +} + +// static +bool CrosPowerLibrary::loaded() { + return CrosLibrary::loaded(); +} + +void CrosPowerLibrary::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void CrosPowerLibrary::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +bool CrosPowerLibrary::line_power_on() const { + return status_.line_power_on; +} + +bool CrosPowerLibrary::battery_fully_charged() const { + return status_.line_power_on && + status_.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED; +} + +double CrosPowerLibrary::battery_percentage() const { + return status_.battery_percentage; +} + +base::TimeDelta CrosPowerLibrary::battery_time_to_empty() const { + return base::TimeDelta::FromSeconds(status_.battery_time_to_empty); +} + +base::TimeDelta CrosPowerLibrary::battery_time_to_full() const { + return base::TimeDelta::FromSeconds(status_.battery_time_to_full); +} + +// static +void CrosPowerLibrary::PowerStatusChangedHandler(void* object, + const chromeos::PowerStatus& status) { + CrosPowerLibrary* power = static_cast<CrosPowerLibrary*>(object); + DLOG(INFO) << "Power" << + " lpo=" << status.line_power_on << + " sta=" << status.battery_state << + " per=" << status.battery_percentage << + " tte=" << status.battery_time_to_empty << + " ttf=" << status.battery_time_to_full; + power->status_ = status; + FOR_EACH_OBSERVER(Observer, power->observers_, PowerChanged(power)); +} diff --git a/chrome/browser/chromeos/cros_power_library.h b/chrome/browser/chromeos/cros_power_library.h new file mode 100644 index 0000000..fdd931a --- /dev/null +++ b/chrome/browser/chromeos/cros_power_library.h @@ -0,0 +1,70 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_CROS_POWER_LIBRARY_H_ +#define CHROME_BROWSER_CHROMEOS_CROS_POWER_LIBRARY_H_ + +#include "base/observer_list.h" +#include "base/singleton.h" +#include "base/time.h" +#include "third_party/cros/chromeos_power.h" + +// This class handles the interaction with the ChromeOS power library APIs. +// Classes can add themselves as observers. Users can get an instance of this +// library class like this: CrosPowerLibrary::Get() +class CrosPowerLibrary { + public: + class Observer { + public: + virtual void PowerChanged(CrosPowerLibrary* obj) = 0; + }; + + // This gets the singleton CrosPowerLibrary + static CrosPowerLibrary* Get(); + + // Returns true if the ChromeOS library was loaded. + static bool loaded(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // Whether or not the line power is connected. + bool line_power_on() const; + + // Whether or not the battery is fully charged.. + bool battery_fully_charged() const; + + // The percentage (0-100) of remaining battery. + double battery_percentage() const; + + // The amount of time until battery is empty. + base::TimeDelta battery_time_to_empty() const; + + // The amount of time until battery is full. + base::TimeDelta battery_time_to_full() const; + + private: + friend struct DefaultSingletonTraits<CrosPowerLibrary>; + + CrosPowerLibrary(); + ~CrosPowerLibrary(); + + // This method is called when there's a change in power status. + // This will notify all the Observers. + static void PowerStatusChangedHandler(void* object, + const chromeos::PowerStatus& status); + + ObserverList<Observer> observers_; + + // A reference to the battery power api, to allow callbacks when the battery + // status changes. + chromeos::PowerStatusConnection power_status_connection_; + + // The latest power status. + chromeos::PowerStatus status_; + + DISALLOW_COPY_AND_ASSIGN(CrosPowerLibrary); +}; + +#endif // CHROME_BROWSER_CHROMEOS_CROS_POWER_LIBRARY_H_ diff --git a/chrome/browser/chromeos/network_menu_button.cc b/chrome/browser/chromeos/network_menu_button.cc index 553ca9e..bf8e74c 100644 --- a/chrome/browser/chromeos/network_menu_button.cc +++ b/chrome/browser/chromeos/network_menu_button.cc @@ -4,8 +4,6 @@ #include "chrome/browser/chromeos/network_menu_button.h" -#include <algorithm> - #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/string_util.h" @@ -22,31 +20,22 @@ // static const int NetworkMenuButton::kNumWifiImages = 8; -SkBitmap* NetworkMenuButton::wifi_images_[kNumWifiImages]; -SkBitmap* NetworkMenuButton::wired_image_ = NULL; -SkBitmap* NetworkMenuButton::disconnected_image_ = NULL; const int NetworkMenuButton::kAnimationDelayMillis = 100; -NetworkMenuButton::NetworkMenuButton(Browser* browser, bool cros_library_loaded) +NetworkMenuButton::NetworkMenuButton(Browser* browser) : MenuButton(NULL, std::wstring(), this, false), - cros_library_loaded_(cros_library_loaded), refreshing_menu_(false), - ethernet_connected_(false), network_menu_(this), browser_(browser), icon_animation_index_(0), icon_animation_increasing_(true) { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - int image_index = IDR_STATUSBAR_WIFI_1; - for (int i = 0; i < kNumWifiImages; i++) - wifi_images_[i] = rb.GetBitmapNamed(image_index + i); - wired_image_ = rb.GetBitmapNamed(IDR_STATUSBAR_WIRED); - disconnected_image_ = rb.GetBitmapNamed(IDR_STATUSBAR_DISCONNECTED); - initialized = true; - } - RefreshNetworks(); + SetShowHighlighted(false); + UpdateIcon(); + CrosNetworkLibrary::Get()->AddObserver(this); +} + +NetworkMenuButton::~NetworkMenuButton() { + CrosNetworkLibrary::Get()->RemoveObserver(this); } //////////////////////////////////////////////////////////////////////////////// @@ -55,30 +44,28 @@ NetworkMenuButton::NetworkMenuButton(Browser* browser, bool cros_library_loaded) int NetworkMenuButton::GetItemCount() const { // The menu contains the available wifi networks. If there are none, then it // only has one item with a message that no networks are available. - return wifi_networks_in_menu_.empty() ? 1 : - static_cast<int>(wifi_networks_in_menu_.size()); + return wifi_networks_.empty() ? 1 : static_cast<int>(wifi_networks_.size()); } views::Menu2Model::ItemType NetworkMenuButton::GetTypeAt(int index) const { - return wifi_networks_in_menu_.empty() ? views::Menu2Model::TYPE_COMMAND : + return wifi_networks_.empty() ? views::Menu2Model::TYPE_COMMAND : views::Menu2Model::TYPE_CHECK; } string16 NetworkMenuButton::GetLabelAt(int index) const { - return wifi_networks_in_menu_.empty() ? + return wifi_networks_.empty() ? l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_NETWORKS_MESSAGE) : - ASCIIToUTF16(wifi_networks_in_menu_[index].ssid); + ASCIIToUTF16(wifi_networks_[index].ssid); } bool NetworkMenuButton::IsItemCheckedAt(int index) const { - // Network that we are connected to (or currently connecting to) is checked. - return wifi_networks_in_menu_.empty() ? false : - wifi_networks_in_menu_[index].ssid == current_ssid_ || - wifi_networks_in_menu_[index].ssid == connecting_ssid_; + // WifiNetwork that we are connected to (or connecting to) is checked. + return wifi_networks_.empty() ? false : + wifi_networks_[index].ssid == CrosNetworkLibrary::Get()->wifi_ssid(); } bool NetworkMenuButton::IsEnabledAt(int index) const { - return !wifi_networks_in_menu_.empty(); + return !wifi_networks_.empty(); } void NetworkMenuButton::ActivatedAt(int index) { @@ -86,21 +73,23 @@ void NetworkMenuButton::ActivatedAt(int index) { if (refreshing_menu_) return; - // We need to look up the ssid in ssids_in_menu_. - std::string ssid = wifi_networks_in_menu_[index].ssid; + CrosNetworkLibrary* cros = CrosNetworkLibrary::Get(); // If clicked on a network that we are already connected to or we are // currently trying to connect to, then do nothing. - if (ssid == current_ssid_ || ssid == connecting_ssid_) + if (wifi_networks_[index].ssid == cros->wifi_ssid()) return; + activated_wifi_network_ = wifi_networks_[index]; + // If wifi network is not encrypted, then directly connect. // Otherwise, we open password dialog window. - if (!wifi_networks_in_menu_[index].encrypted) { - ConnectToWifiNetwork(ssid, string16()); + if (!wifi_networks_[index].encrypted) { + cros->ConnectToWifiNetwork(wifi_networks_[index], string16()); } else { gfx::NativeWindow parent = browser_->window()->GetNativeHandle(); - PasswordDialogView* dialog = new PasswordDialogView(this, ssid); + PasswordDialogView* dialog = new PasswordDialogView(this, + wifi_networks_[index].ssid); views::Window* window = views::Window::CreateChromeWindow( parent, gfx::Rect(), dialog); // Draw the password dialog right below this button and right aligned. @@ -118,7 +107,9 @@ void NetworkMenuButton::ActivatedAt(int index) { bool NetworkMenuButton::OnPasswordDialogAccept(const std::string& ssid, const string16& password) { - return ConnectToWifiNetwork(ssid, password); + CrosNetworkLibrary::Get()->ConnectToWifiNetwork(activated_wifi_network_, + password); + return true; } //////////////////////////////////////////////////////////////////////////////// @@ -126,9 +117,7 @@ bool NetworkMenuButton::OnPasswordDialogAccept(const std::string& ssid, void NetworkMenuButton::RunMenu(views::View* source, const gfx::Point& pt, gfx::NativeView hwnd) { - RefreshNetworks(); - // Make a copy of the wifi networks that we are showing because it may change. - wifi_networks_in_menu_ = wifi_networks_; + wifi_networks_ = CrosNetworkLibrary::Get()->GetWifiNetworks(); refreshing_menu_ = true; network_menu_.Rebuild(); network_menu_.UpdateStates(); @@ -136,128 +125,16 @@ void NetworkMenuButton::RunMenu(views::View* source, const gfx::Point& pt, network_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); } -bool NetworkMenuButton::GetWifiNetwork(const WifiNetworkVector& networks, - const std::string& ssid, - WifiNetwork* network) { - WifiNetworkVector::const_iterator it; - for (it = networks.begin(); it != networks.end(); ++it) { - if (it->ssid == ssid) { - *network = *it; - return true; - } - } - return false; -} - -void NetworkMenuButton::AddWifiNetwork(const std::string& ssid, - bool encrypted, - chromeos::EncryptionType encryption, - int strength) { - wifi_networks_.push_back( - WifiNetwork(ssid, encrypted, encryption, strength)); -} - -void NetworkMenuButton::RefreshNetworks() { - std::string current; - std::string connecting; - wifi_networks_.clear(); - ethernet_connected_ = false; +//////////////////////////////////////////////////////////////////////////////// +// NetworkMenuButton, CrosNetworkLibrary::Observer implementation: - if (cros_library_loaded_) { - chromeos::ServiceStatus* service_status = chromeos::GetAvailableNetworks(); - for (int i = 0; i < service_status->size; i++) { - chromeos::ServiceInfo service = service_status->services[i]; - std::string ssid = service.ssid; - DLOG(WARNING) << "Found network type=" << service.type << - " ssid=" << service.ssid << - " state=" << service.state << - " needs_passphrase=" << service.needs_passphrase << - " encryption=" << service.encryption << - " signal_strength=" << service.signal_strength; - if (service.type == chromeos::TYPE_WIFI) { - AddWifiNetwork(ssid, service.needs_passphrase, service.encryption, - service.signal_strength); - // Check connection state. - switch (service.state) { - case chromeos::STATE_ASSOCIATION: // connecting to access point - case chromeos::STATE_CONFIGURATION: // optaining ip address - connecting = ssid; - break; - case chromeos::STATE_READY: // connected and has ip - current = ssid; - break; - case chromeos::STATE_FAILURE: // failed to connect - // TODO(chocobo): Handle failure. Show it to user. - DLOG(WARNING) << "Wifi network failed to connect: " << ssid; - break; - case chromeos::STATE_IDLE: // no connection - case chromeos::STATE_DISCONNECT: // disconnected - case chromeos::STATE_CARRIER: // not used - case chromeos::STATE_UNKNOWN: // unknown - default: - break; - } - } else if (service.type == chromeos::TYPE_ETHERNET) { - if (service.state == chromeos::STATE_READY) - ethernet_connected_ = true; - } - } - chromeos::FreeServiceStatus(service_status); +void NetworkMenuButton::NetworkChanged(CrosNetworkLibrary* obj) { + if (CrosNetworkLibrary::Get()->wifi_connecting()) { + StartConnectingAnimation(); } else { - // Use test data if ChromeOS shared library is not loaded. - AddWifiNetwork("Wifi (12)", false, chromeos::NONE, 12); - AddWifiNetwork("Wifi RSN (70)", true, chromeos::RSN, 70); - AddWifiNetwork("Wifi (28)", false, chromeos::NONE, 28); - AddWifiNetwork("Wifi WEP (99)", true, chromeos::WEP, 99); - current = connecting_ssid_.empty() ? current_ssid_ : connecting_ssid_; - ethernet_connected_ = true; - } - - // Sort the list of wifi networks by ssid. - std::sort(wifi_networks_.begin(), wifi_networks_.end()); - - connecting_ssid_ = connecting; - current_ssid_ = current; - - if (connecting_ssid_.empty()) { StopConnectingAnimation(); UpdateIcon(); - } else { - StartConnectingAnimation(); - } -} - -static const char* GetEncryptionString(chromeos::EncryptionType encryption) { - switch (encryption) { - case chromeos::NONE: - return "none"; - case chromeos::RSN: - return "rsn"; - case chromeos::WEP: - return "wep"; - case chromeos::WPA: - return "wpa"; } - return "none"; -} - -bool NetworkMenuButton::ConnectToWifiNetwork(const std::string& ssid, - const string16& password) { - bool ok = true; - if (cros_library_loaded_) { - chromeos::EncryptionType encryption = chromeos::NONE; - WifiNetwork network; - if (GetWifiNetwork(wifi_networks_in_menu_, ssid, &network)) - encryption = network.encryption; - ok = chromeos::ConnectToWifiNetwork(ssid.c_str(), - password.empty() ? NULL : UTF16ToUTF8(password).c_str(), - GetEncryptionString(encryption)); - } - if (ok) { - connecting_ssid_ = ssid; - StartConnectingAnimation(); - } - return true; } void NetworkMenuButton::StartConnectingAnimation() { @@ -276,7 +153,9 @@ void NetworkMenuButton::StopConnectingAnimation() { } void NetworkMenuButton::UpdateIcon() { - if (!connecting_ssid_.empty()) { + CrosNetworkLibrary* cros = CrosNetworkLibrary::Get(); + int id = IDR_STATUSBAR_DISCONNECTED; + if (cros->wifi_connecting()) { // Get the next frame. Reverse direction if necessary. if (icon_animation_increasing_) { icon_animation_index_++; @@ -291,34 +170,23 @@ void NetworkMenuButton::UpdateIcon() { icon_animation_increasing_ = true; } } - SetIcon(*wifi_images_[icon_animation_index_]); - - // Refresh wifi networks every full animation. - // And see if we need to stop the animation. - if (icon_animation_index_ == 0) - RefreshNetworks(); + id = IDR_STATUSBAR_WIFI_1 + icon_animation_index_; } else { - if (current_ssid_.empty()) { - if (ethernet_connected_) - SetIcon(*wired_image_); + if (cros->wifi_ssid().empty()) { + if (cros->ethernet_connected()) + id = IDR_STATUSBAR_WIRED; else - SetIcon(*disconnected_image_); + id = IDR_STATUSBAR_DISCONNECTED; } else { - WifiNetwork network; - if (GetWifiNetwork(wifi_networks_, current_ssid_, &network)) { - // Gets the wifi image of 1-8 bars depending on signal strength. Signal - // strength is from 0 to 100, so we need to convert that to 0 to 7. - int index = floor(network.strength / (100.0 / kNumWifiImages)); - // This can happen if the signal strength is 100. - if (index == kNumWifiImages) - index--; - SetIcon(*wifi_images_[index]); - } else { - // We no longer find the current network in the list of networks. - // So just set the icon to the disconnected image. - SetIcon(*disconnected_image_); - } + // Gets the wifi image of 1-8 bars depending on signal strength. Signal + // strength is from 0 to 100, so we need to convert that to 0 to 7. + int index = floor(cros->wifi_strength() / (100.0 / kNumWifiImages)); + // This can happen if the signal strength is 100. + if (index == kNumWifiImages) + index--; + id = IDR_STATUSBAR_WIFI_1 + index; } } + SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(id)); SchedulePaint(); } diff --git a/chrome/browser/chromeos/network_menu_button.h b/chrome/browser/chromeos/network_menu_button.h index 6b0a0ef..6f6fe38 100644 --- a/chrome/browser/chromeos/network_menu_button.h +++ b/chrome/browser/chromeos/network_menu_button.h @@ -6,38 +6,16 @@ #define CHROME_BROWSER_CHROMEOS_NETWORK_MENU_BUTTON_H_ #include <string> -#include <vector> #include "base/timer.h" +#include "chrome/browser/chromeos/cros_network_library.h" #include "chrome/browser/chromeos/password_dialog_view.h" -#include "third_party/cros/chromeos_network.h" -#include "third_party/skia/include/core/SkBitmap.h" #include "views/controls/button/menu_button.h" #include "views/controls/menu/menu_2.h" #include "views/controls/menu/view_menu_delegate.h" class Browser; - -struct WifiNetwork { - WifiNetwork() : encrypted(false), strength(0) { } - WifiNetwork(const std::string& ssid, bool encrypted, - chromeos::EncryptionType encryption, int strength) - : ssid(ssid), - encrypted(encrypted), - encryption(encryption), - strength(strength) { } - - // WifiNetworks are sorted by ssids. - bool operator< (const WifiNetwork& other) const { - return ssid < other.ssid; - } - - std::string ssid; - bool encrypted; - chromeos::EncryptionType encryption; - int strength; -}; -typedef std::vector<WifiNetwork> WifiNetworkVector; +class SkBitmap; // The network menu button in the status area. // This class will handle getting the wifi networks and populating the menu. @@ -46,10 +24,11 @@ typedef std::vector<WifiNetwork> WifiNetworkVector; class NetworkMenuButton : public views::MenuButton, public views::ViewMenuDelegate, public views::Menu2Model, - public PasswordDialogDelegate { + public PasswordDialogDelegate, + public CrosNetworkLibrary::Observer { public: - NetworkMenuButton(Browser* browser, bool cros_library_loaded); - virtual ~NetworkMenuButton() {} + explicit NetworkMenuButton(Browser* browser); + virtual ~NetworkMenuButton(); // views::Menu2Model implementation. virtual bool HasIcons() const { return false; } @@ -74,28 +53,14 @@ class NetworkMenuButton : public views::MenuButton, virtual bool OnPasswordDialogAccept(const std::string& ssid, const string16& password); + // CrosNetworkLibrary::Observer implementation. + virtual void NetworkChanged(CrosNetworkLibrary* obj); + private: // views::ViewMenuDelegate implementation. virtual void RunMenu(views::View* source, const gfx::Point& pt, gfx::NativeView hwnd); - // Gets the WifiNetwork for the given ssid in the list of wifi networks. - // Returns whether or not WifiNetwork was found. - bool GetWifiNetwork(const WifiNetworkVector& networks, - const std::string& ssid, - WifiNetwork* network); - - // Helper method to add a wifi network to the model. - void AddWifiNetwork(const std::string& ssid, bool encrypted, - chromeos::EncryptionType encryption, int strength); - - // Refreshes the networks model using real data. - void RefreshNetworks(); - - // Connect to the specified wireless network with password. - // Returns whether or not connection was successful. - bool ConnectToWifiNetwork(const std::string& ssid, const string16& password); - // Start animating the icon to show that we are connecting to a network. void StartConnectingAnimation(); @@ -105,38 +70,17 @@ class NetworkMenuButton : public views::MenuButton, // Update the icon to either the connecting, connected, or disconnected icon. void UpdateIcon(); - // Whether or not the cros shared library loaded successfully or not. - bool cros_library_loaded_; - // Set to true if we are currently refreshing the menu. bool refreshing_menu_; // The number of wifi strength images. static const int kNumWifiImages; - // Wifi strength images. - static SkBitmap* wifi_images_[]; - - // Wired image. - static SkBitmap* wired_image_; - - // Disconnected image. - static SkBitmap* disconnected_image_; - - // Whether or not ethernet is connected. - bool ethernet_connected_; - - // The currently connected wifi network ssid. - std::string current_ssid_; - - // The wifi netowrk ssid we are attempting to connect to. - std::string connecting_ssid_; - // A list of wifi networks. WifiNetworkVector wifi_networks_; - // A list of wifi networks that we are currently showing in the menu. - WifiNetworkVector wifi_networks_in_menu_; + // The activated wifi network. + WifiNetwork activated_wifi_network_; // The network menu. views::Menu2 network_menu_; diff --git a/chrome/browser/chromeos/power_menu_button.cc b/chrome/browser/chromeos/power_menu_button.cc new file mode 100644 index 0000000..cdf6999 --- /dev/null +++ b/chrome/browser/chromeos/power_menu_button.cc @@ -0,0 +1,126 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/power_menu_button.h" + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/time.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" + +//////////////////////////////////////////////////////////////////////////////// +// PowerMenuButton + +// static +const int PowerMenuButton::kNumPowerImages = 8; + +PowerMenuButton::PowerMenuButton() + : MenuButton(NULL, std::wstring(), this, false), + ALLOW_THIS_IN_INITIALIZER_LIST(power_menu_(this)) { + SetShowHighlighted(false); + UpdateIcon(); + CrosPowerLibrary::Get()->AddObserver(this); +} + +PowerMenuButton::~PowerMenuButton() { + CrosPowerLibrary::Get()->RemoveObserver(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// PowerMenuButton, views::Menu2Model implementation: + +int PowerMenuButton::GetItemCount() const { + return 2; +} + +views::Menu2Model::ItemType PowerMenuButton::GetTypeAt(int index) const { + return views::Menu2Model::TYPE_COMMAND; +} + +string16 PowerMenuButton::GetLabelAt(int index) const { + CrosPowerLibrary* cros = CrosPowerLibrary::Get(); + // The first item shows the percentage of battery left. + if (index == 0) { + // If fully charged, always show 100% even if internal number is a bit less. + double percent = cros->battery_fully_charged() ? 100 : + cros->battery_percentage(); + return l10n_util::GetStringFUTF16(IDS_STATUSBAR_BATTERY_PERCENTAGE, + IntToString16(static_cast<int>(percent))); + } + + // The second item shows the battery is charged if it is. + if (cros->battery_fully_charged()) + return l10n_util::GetStringUTF16(IDS_STATUSBAR_BATTERY_IS_CHARGED); + + // If battery is in an intermediate charge state, we show how much time left. + base::TimeDelta time = cros->line_power_on() ? cros->battery_time_to_full() : + cros->battery_time_to_empty(); + if (time.InSeconds() == 0) { + // If time is 0, then that means we are still calculating how much time. + // Depending if line power is on, we either show a message saying that we + // are calculating time until full or calculating remaining time. + int msg = cros->line_power_on() ? + IDS_STATUSBAR_BATTERY_CALCULATING_TIME_UNTIL_FULL : + IDS_STATUSBAR_BATTERY_CALCULATING_TIME_UNTIL_EMPTY; + return l10n_util::GetStringUTF16(msg); + } else { + // Depending if line power is on, we either show a message saying XX:YY + // until full or XX:YY remaining where XX is number of hours and YY is + // number of minutes. + int msg = cros->line_power_on() ? IDS_STATUSBAR_BATTERY_TIME_UNTIL_FULL : + IDS_STATUSBAR_BATTERY_TIME_UNTIL_EMPTY; + int hour = time.InHours(); + int min = (time - base::TimeDelta::FromHours(hour)).InMinutes(); + string16 hour_str = IntToString16(hour); + string16 min_str = IntToString16(min); + // Append a "0" before the minute if it's only a single digit. + if (min < 10) + min_str = ASCIIToUTF16("0") + min_str; + return l10n_util::GetStringFUTF16(msg, hour_str, min_str); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// PowerMenuButton, views::ViewMenuDelegate implementation: + +void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt, + gfx::NativeView hwnd) { + power_menu_.Rebuild(); + power_menu_.UpdateStates(); + power_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); +} + +//////////////////////////////////////////////////////////////////////////////// +// PowerMenuButton, CrosPowerLibrary::Observer implementation: + +void PowerMenuButton::PowerChanged(CrosPowerLibrary* obj) { + UpdateIcon(); +} + +void PowerMenuButton::UpdateIcon() { + CrosPowerLibrary* cros = CrosPowerLibrary::Get(); + int id = IDR_STATUSBAR_BATTERY_UNKNOWN; + if (CrosPowerLibrary::loaded()) { + if (cros->battery_fully_charged()) { + id = IDR_STATUSBAR_BATTERY_CHARGED; + } else { + // If fully charged, always show 100% even if percentage is a bit less. + double percent = cros->battery_fully_charged() ? 100 : + cros->battery_percentage(); + // Gets the power image depending on battery percentage. Percentage is + // from 0 to 100, so we need to convert that to 0 to kNumPowerImages - 1. + int index = floor(percent / (100.0 / kNumPowerImages)); + // This can happen if the battery is 100% full. + if (index == kNumPowerImages) + index--; + if (cros->line_power_on()) + id = IDR_STATUSBAR_BATTERY_CHARGING_1 + index; + else + id = IDR_STATUSBAR_BATTERY_DISCHARGING_1 + index; + } + } + SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(id)); + SchedulePaint(); +} diff --git a/chrome/browser/chromeos/power_menu_button.h b/chrome/browser/chromeos/power_menu_button.h new file mode 100644 index 0000000..4c3252a --- /dev/null +++ b/chrome/browser/chromeos/power_menu_button.h @@ -0,0 +1,65 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_POWER_MENU_BUTTON_H_ +#define CHROME_BROWSER_CHROMEOS_POWER_MENU_BUTTON_H_ + +#include "chrome/browser/chromeos/cros_power_library.h" +#include "views/controls/button/menu_button.h" +#include "views/controls/menu/menu_2.h" +#include "views/controls/menu/view_menu_delegate.h" + +class CrosPowerLibrary; +class SkBitmap; + +// The power menu button in the status area. +// This class will handle getting the power status and populating the menu. +// It handles the status icon changing and connecting to another wifi power. +class PowerMenuButton : public views::MenuButton, + public views::ViewMenuDelegate, + public views::Menu2Model, + public CrosPowerLibrary::Observer { + public: + PowerMenuButton(); + virtual ~PowerMenuButton(); + + // views::Menu2Model implementation. + virtual bool HasIcons() const { return false; } + virtual int GetItemCount() const; + virtual views::Menu2Model::ItemType GetTypeAt(int index) const; + virtual int GetCommandIdAt(int index) const { return index; } + virtual string16 GetLabelAt(int index) const; + virtual bool IsLabelDynamicAt(int index) const { return true; } + virtual bool GetAcceleratorAt(int index, + views::Accelerator* accelerator) const { return false; } + virtual bool IsItemCheckedAt(int index) const { return false; } + virtual int GetGroupIdAt(int index) const { return 0; } + virtual bool GetIconAt(int index, SkBitmap* icon) const { return false; } + virtual bool IsEnabledAt(int index) const { return false; } + virtual Menu2Model* GetSubmenuModelAt(int index) const { return NULL; } + virtual void HighlightChangedTo(int index) {} + virtual void ActivatedAt(int index) {} + virtual void MenuWillShow() {} + + // CrosPowerLibrary::Observer implementation. + virtual void PowerChanged(CrosPowerLibrary* obj); + + private: + // views::ViewMenuDelegate implementation. + virtual void RunMenu(views::View* source, const gfx::Point& pt, + gfx::NativeView hwnd); + + // Update the power icon depending on the power status. + void UpdateIcon(); + + // The number of power images. + static const int kNumPowerImages; + + // The power menu. + views::Menu2 power_menu_; + + DISALLOW_COPY_AND_ASSIGN(PowerMenuButton); +}; + +#endif // CHROME_BROWSER_CHROMEOS_POWER_MENU_BUTTON_H_ diff --git a/chrome/browser/chromeos/settings_contents_view.cc b/chrome/browser/chromeos/settings_contents_view.cc index 6a59d34..d0e5922 100644 --- a/chrome/browser/chromeos/settings_contents_view.cc +++ b/chrome/browser/chromeos/settings_contents_view.cc @@ -13,6 +13,7 @@ #include "app/resource_bundle.h" #include "base/basictypes.h" #include "base/string_util.h" +#include "chrome/browser/chromeos/cros_network_library.h" #include "chrome/browser/chromeos/password_dialog_view.h" #include "chrome/common/pref_member.h" #include "chrome/common/pref_names.h" @@ -32,92 +33,53 @@ using views::ColumnSet; namespace { //////////////////////////////////////////////////////////////////////////////// -// WifiSSIDComboModel +// WifiNetworkComboModel // The Combobox model for the list of wifi networks -class WifiSSIDComboModel : public ComboboxModel { +class WifiNetworkComboModel : public ComboboxModel { public: - struct NetworkData { - NetworkData() { } - NetworkData(const string16& encryption, const int& strength) - : encryption(encryption), - strength(strength) { } - - string16 encryption; - int strength; - }; - typedef std::map<std::string, NetworkData> NetworkDataMap; - - WifiSSIDComboModel(); + WifiNetworkComboModel(); virtual int GetItemCount(); virtual std::wstring GetItemAt(int index); - const std::string& GetSSIDAt(int index); - bool RequiresPassword(const std::string& ssid); + bool HasWifiNetworks(); + const WifiNetwork& GetWifiNetworkAt(int index); private: - std::vector<std::string> ssids_; - - // A map of some extra data (NetworkData) keyed off the ssids. - NetworkDataMap ssids_map_; - - void AddWifiNetwork(const std::string& ssid, - const string16& encryption, - int strength); + WifiNetworkVector wifi_networks_; - DISALLOW_COPY_AND_ASSIGN(WifiSSIDComboModel); + DISALLOW_COPY_AND_ASSIGN(WifiNetworkComboModel); }; -WifiSSIDComboModel::WifiSSIDComboModel() { - // TODO(chocobo): Load wifi info from conman. - // This is just temporary data until we hook this up to real data. - AddWifiNetwork("Wifi Combobox Mock", string16(), 80); - AddWifiNetwork("Wifi WPA-PSK Password is chronos", - ASCIIToUTF16("WPA-PSK"), 60); - AddWifiNetwork("Wifi No Encryption", string16(), 90); +WifiNetworkComboModel::WifiNetworkComboModel() { + wifi_networks_ = CrosNetworkLibrary::Get()->GetWifiNetworks(); } -int WifiSSIDComboModel::GetItemCount() { - return static_cast<int>(ssids_.size()); +int WifiNetworkComboModel::GetItemCount() { + // Item count is always 1 more than number of networks. + // If there are no networks, then we show a message stating that. + // If there are networks, the first item is empty. + return static_cast<int>(wifi_networks_.size()) + 1; } -std::wstring WifiSSIDComboModel::GetItemAt(int index) { - DCHECK(static_cast<int>(ssids_.size()) > index); - - NetworkDataMap::const_iterator it = ssids_map_.find(ssids_[index]); - DCHECK(it != ssids_map_.end()); - - // TODO(chocobo): Finalize UI, then put strings in resource file. - std::vector<string16> subst; - subst.push_back(ASCIIToUTF16(it->first)); // $1 - // The "None" string is just temporary for now. Have not finalized the UI yet. - if (it->second.encryption.empty()) - subst.push_back(ASCIIToUTF16("None")); // $2 - else - subst.push_back(it->second.encryption); // $2 - subst.push_back(IntToString16(it->second.strength)); // $3 - - return UTF16ToWide( - ReplaceStringPlaceholders(ASCIIToUTF16("$1 ($2, $3)"), subst, NULL)); -} - -const std::string& WifiSSIDComboModel::GetSSIDAt(int index) { - DCHECK(static_cast<int>(ssids_.size()) > index); - return ssids_[index]; +std::wstring WifiNetworkComboModel::GetItemAt(int index) { + if (index == 0) { + return wifi_networks_.empty() ? + l10n_util::GetString(IDS_STATUSBAR_NO_NETWORKS_MESSAGE) : + ASCIIToWide(""); + } + // If index is greater than one, we get the corresponding network, which is + // in the wifi_networks_ list in [index-1] position. + return ASCIIToWide(wifi_networks_[index-1].ssid); } -bool WifiSSIDComboModel::RequiresPassword(const std::string& ssid) { - NetworkDataMap::const_iterator it = ssids_map_.find(ssid); - DCHECK(it != ssids_map_.end()); - return !it->second.encryption.empty(); +bool WifiNetworkComboModel::HasWifiNetworks() { + return !wifi_networks_.empty(); } -void WifiSSIDComboModel::AddWifiNetwork(const std::string& ssid, - const string16& encryption, - int strength) { - ssids_.push_back(ssid); - ssids_map_[ssid] = NetworkData(encryption, strength); +const WifiNetwork& WifiNetworkComboModel::GetWifiNetworkAt(int index) { + return wifi_networks_[index-1]; } //////////////////////////////////////////////////////////////////////////////// @@ -126,10 +88,11 @@ void WifiSSIDComboModel::AddWifiNetwork(const std::string& ssid, // Network section for wifi settings class NetworkSection : public OptionsPageView, public views::Combobox::Listener, - public PasswordDialogDelegate { + public PasswordDialogDelegate, + public CrosNetworkLibrary::Observer { public: explicit NetworkSection(Profile* profile); - virtual ~NetworkSection() {} + virtual ~NetworkSection(); // Overridden from views::Combobox::Listener: virtual void ItemChanged(views::Combobox* sender, @@ -141,7 +104,8 @@ class NetworkSection : public OptionsPageView, virtual bool OnPasswordDialogAccept(const std::string& ssid, const string16& password); - bool ConnectToWifi(const std::string& ssid, const string16& password); + // CrosNetworkLibrary::Observer implementation. + virtual void NetworkChanged(CrosNetworkLibrary* obj); protected: // OptionsPageView overrides: @@ -158,8 +122,11 @@ class NetworkSection : public OptionsPageView, // Used to store the index (in combobox) of the currently connected wifi. int last_selected_wifi_ssid_index_; - // Dummy for now. Used to populate wifi ssid models. - WifiSSIDComboModel wifi_ssid_model_; + // The activated wifi network. + WifiNetwork activated_wifi_network_; + + // The wifi ssid models. + WifiNetworkComboModel wifi_ssid_model_; DISALLOW_COPY_AND_ASSIGN(NetworkSection); }; @@ -172,6 +139,11 @@ NetworkSection::NetworkSection(Profile* profile) contents_(NULL), wifi_ssid_combobox_(NULL), last_selected_wifi_ssid_index_(0) { + CrosNetworkLibrary::Get()->AddObserver(this); +} + +NetworkSection::~NetworkSection() { + CrosNetworkLibrary::Get()->RemoveObserver(this); } void NetworkSection::ItemChanged(views::Combobox* sender, @@ -179,39 +151,56 @@ void NetworkSection::ItemChanged(views::Combobox* sender, int new_index) { if (new_index == prev_index) return; - if (sender == wifi_ssid_combobox_) { - last_selected_wifi_ssid_index_ = prev_index; - std::string ssid = wifi_ssid_model_.GetSSIDAt(new_index); - // Connect to wifi here. Open password page if appropriate - if (wifi_ssid_model_.RequiresPassword(ssid)) { - views::Window* window = views::Window::CreateChromeWindow( - NULL, - gfx::Rect(), - new PasswordDialogView(this, ssid)); - window->SetIsAlwaysOnTop(true); - window->Show(); - } else { - ConnectToWifi(ssid, string16()); - } + + // Don't allow switching to the first item (which is empty). + if (new_index == 0) { + wifi_ssid_combobox_->SetSelectedItem(prev_index); + return; + } + + if (!wifi_ssid_model_.HasWifiNetworks()) + return; + + last_selected_wifi_ssid_index_ = prev_index; + activated_wifi_network_ = wifi_ssid_model_.GetWifiNetworkAt(new_index); + // Connect to wifi here. Open password page if appropriate. + if (activated_wifi_network_.encrypted) { + views::Window* window = views::Window::CreateChromeWindow( + NULL, + gfx::Rect(), + new PasswordDialogView(this, activated_wifi_network_.ssid)); + window->SetIsAlwaysOnTop(true); + window->Show(); + } else { + CrosNetworkLibrary::Get()->ConnectToWifiNetwork(activated_wifi_network_, + string16()); } } bool NetworkSection::OnPasswordDialogCancel() { - // Change combobox to previous setting + // Change combobox to previous setting. wifi_ssid_combobox_->SetSelectedItem(last_selected_wifi_ssid_index_); return true; } bool NetworkSection::OnPasswordDialogAccept(const std::string& ssid, const string16& password) { - // Try connecting to wifi - return ConnectToWifi(ssid, password); + CrosNetworkLibrary::Get()->ConnectToWifiNetwork(activated_wifi_network_, + password); + return true; } -bool NetworkSection::ConnectToWifi(const std::string& ssid, - const string16& password) { - // TODO(chocobo): Connect to wifi - return password == ASCIIToUTF16("chronos"); +void NetworkSection::NetworkChanged(CrosNetworkLibrary* obj) { + if (wifi_ssid_model_.HasWifiNetworks()) { + for (int i = 1; i < wifi_ssid_model_.GetItemCount(); i++) { + if (wifi_ssid_model_.GetWifiNetworkAt(i).ssid == obj->wifi_ssid()) { + last_selected_wifi_ssid_index_ = i; + if (wifi_ssid_combobox_) + wifi_ssid_combobox_->SetSelectedItem(i); + return; + } + } + } } void NetworkSection::InitControlLayout() { @@ -248,6 +237,7 @@ void NetworkSection::InitContents() { contents_->SetLayoutManager(layout); wifi_ssid_combobox_ = new views::Combobox(&wifi_ssid_model_); + wifi_ssid_combobox_->SetSelectedItem(last_selected_wifi_ssid_index_); wifi_ssid_combobox_->set_listener(this); int single_column_view_set_id = 0; @@ -474,10 +464,9 @@ void SettingsContentsView::InitControlLayout() { column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, 0); - // TODO(chocobo): Add NetworkSection back in when we finalized the UI. -// layout->StartRow(0, single_column_view_set_id); -// layout->AddView(new NetworkSection(profile())); -// layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + layout->StartRow(0, single_column_view_set_id); + layout->AddView(new NetworkSection(profile())); + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); layout->StartRow(0, single_column_view_set_id); layout->AddView(new TouchpadSection(profile())); layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); diff --git a/chrome/browser/chromeos/status_area_view.cc b/chrome/browser/chromeos/status_area_view.cc index 41388a0..ed17b6d 100755 --- a/chrome/browser/chromeos/status_area_view.cc +++ b/chrome/browser/chromeos/status_area_view.cc @@ -4,128 +4,35 @@ #include "chrome/browser/chromeos/status_area_view.h" -#include <dlfcn.h> - #include <algorithm> #include "app/gfx/canvas.h" -#include "app/gfx/font.h" #include "app/l10n_util.h" -#include "app/resource_bundle.h" #include "app/theme_provider.h" -#include "base/path_service.h" #include "base/string_util.h" -#include "base/time.h" -#include "base/timer.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" +#include "chrome/browser/chromeos/clock_menu_button.h" #include "chrome/browser/chromeos/network_menu_button.h" +#include "chrome/browser/chromeos/power_menu_button.h" #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/profile.h" -#include "chrome/common/chrome_paths.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "views/controls/button/menu_button.h" -#include "views/controls/image_view.h" #include "views/controls/menu/menu.h" #include "views/controls/menu/simple_menu_model.h" namespace { -// The number of images representing the fullness of the battery. -const int kNumBatteryImages = 8; - // Number of pixels to separate adjacent status items. const int kStatusItemSeparation = 1; // BrowserWindowGtk tiles its image with this offset const int kCustomFrameBackgroundVerticalOffset = 15; -class ClockView : public views::View { - public: - ClockView(); - virtual ~ClockView(); - - // views::View* overrides. - virtual gfx::Size GetPreferredSize(); - virtual void Paint(gfx::Canvas* canvas); - - private: - // Schedules the timer to fire at the next minute interval. - void SetNextTimer(); - - // Schedules a paint when the timer goes off. - void OnTimer(); - - gfx::Font font_; - - base::OneShotTimer<ClockView> timer_; - - DISALLOW_COPY_AND_ASSIGN(ClockView); -}; - -// Amount of slop to add into the timer to make sure we're into the next minute -// when the timer goes off. -const int kTimerSlopSeconds = 1; - -ClockView::ClockView() - : font_(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD)) { - SetNextTimer(); -} - -ClockView::~ClockView() { -} - -gfx::Size ClockView::GetPreferredSize() { - return gfx::Size(40, 12); -} - -void ClockView::Paint(gfx::Canvas* canvas) { - base::Time now = base::Time::Now(); - base::Time::Exploded now_exploded; - now.LocalExplode(&now_exploded); - int hour = now_exploded.hour % 12; - if (hour == 0) - hour = 12; - - std::wstring time_string = StringPrintf(L"%d:%02d%lc", - hour, - now_exploded.minute, - now_exploded.hour < 12 ? L'p' : L'p'); - canvas->DrawStringInt(time_string, font_, SK_ColorWHITE, 0, 0, - width(), height(), gfx::Canvas::TEXT_ALIGN_CENTER); -} - -void ClockView::SetNextTimer() { - // Try to set the timer to go off at the next change of the minute. We don't - // want to have the timer go off more than necessary since that will cause - // the CPU to wake up and consume power. - base::Time now = base::Time::Now(); - base::Time::Exploded exploded; - now.LocalExplode(&exploded); - - // Often this will be called at minute boundaries, and we'll actually want - // 60 seconds from now. - int seconds_left = 60 - exploded.second; - if (seconds_left == 0) - seconds_left = 60; - - // Make sure that the timer fires on the next minute. Without this, if it is - // called just a teeny bit early, then it will skip the next minute. - seconds_left += kTimerSlopSeconds; - - timer_.Start(base::TimeDelta::FromSeconds(seconds_left), - this, &ClockView::OnTimer); -} - -void ClockView::OnTimer() { - SchedulePaint(); - SetNextTimer(); -} - class OptionsMenuModel : public views::SimpleMenuModel, public views::SimpleMenuModel::Delegate { public: @@ -200,49 +107,34 @@ class OptionsMenuModel : public views::SimpleMenuModel, StatusAreaView::OpenTabsMode StatusAreaView::open_tabs_mode_ = StatusAreaView::OPEN_TABS_ON_LEFT; -// static -bool StatusAreaView::cros_library_loaded_ = false; -bool StatusAreaView::cros_library_error_ = false; - StatusAreaView::StatusAreaView(Browser* browser) : browser_(browser), + clock_view_(NULL), network_view_(NULL), battery_view_(NULL), - menu_view_(NULL), - power_status_connection_(NULL) { -} - -StatusAreaView::~StatusAreaView() { - if (power_status_connection_) - chromeos::DisconnectPowerStatus(power_status_connection_); + menu_view_(NULL) { } void StatusAreaView::Init() { - LoadCrosLibrary(); ThemeProvider* theme = browser_->profile()->GetThemeProvider(); // Clock. - AddChildView(new ClockView); + clock_view_ = new ClockMenuButton(); + AddChildView(clock_view_); // Network. - network_view_ = new NetworkMenuButton(browser_, cros_library_loaded_); + network_view_ = new NetworkMenuButton(browser_); AddChildView(network_view_); // Battery. - battery_view_ = new views::ImageView; - battery_view_->SetImage(theme->GetBitmapNamed(IDR_STATUSBAR_BATTERY_UNKNOWN)); + battery_view_ = new PowerMenuButton(); AddChildView(battery_view_); // Menu. menu_view_ = new views::MenuButton(NULL, std::wstring(), this, false); + menu_view_->SetShowHighlighted(false); menu_view_->SetIcon(*theme->GetBitmapNamed(IDR_STATUSBAR_MENU)); AddChildView(menu_view_); - - if (cros_library_loaded_) { - power_status_connection_ = chromeos::MonitorPowerStatus( - StatusAreaView::PowerStatusChangedHandler, - this); - } } gfx::Size StatusAreaView::GetPreferredSize() { @@ -373,54 +265,3 @@ void StatusAreaView::RunMenu(views::View* source, const gfx::Point& pt, app_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); } -// static -void StatusAreaView::LoadCrosLibrary() { - if (cros_library_loaded_) { - // Already loaded. - return; - } - - if (cros_library_error_) { - // Error in previous load attempt. - return; - } - - FilePath path; - if (PathService::Get(chrome::FILE_CHROMEOS_API, &path)) { - cros_library_loaded_ = chromeos::LoadCros(path.value().c_str()); - if (!cros_library_loaded_) { - cros_library_error_ = true; - char* error = dlerror(); - if (error) { - LOG(ERROR) << "Problem loading chromeos shared object: " << error; - } - } - } -} - -// static -void StatusAreaView::PowerStatusChangedHandler( - void* object, const chromeos::PowerStatus& status) { - static_cast<StatusAreaView*>(object)->PowerStatusChanged(status); -} - -void StatusAreaView::PowerStatusChanged(const chromeos::PowerStatus& status) { - ThemeProvider* theme = browser_->profile()->GetThemeProvider(); - int image_index; - - if (status.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED && - status.line_power_on) { - image_index = IDR_STATUSBAR_BATTERY_CHARGED; - } else { - image_index = status.line_power_on ? - IDR_STATUSBAR_BATTERY_CHARGING_1 : - IDR_STATUSBAR_BATTERY_DISCHARGING_1; - double percentage = status.battery_percentage; - int offset = floor(percentage / (100.0 / kNumBatteryImages)); - // This can happen if the battery is 100% full. - if (offset == kNumBatteryImages) - offset--; - image_index += offset; - } - battery_view_->SetImage(theme->GetBitmapNamed(image_index)); -} diff --git a/chrome/browser/chromeos/status_area_view.h b/chrome/browser/chromeos/status_area_view.h index f2c2a1b..76f7873 100755 --- a/chrome/browser/chromeos/status_area_view.h +++ b/chrome/browser/chromeos/status_area_view.h @@ -6,18 +6,17 @@ #define CHROME_BROWSER_CHROMEOS_STATUS_AREA_VIEW_H_ #include "base/basictypes.h" -#include "third_party/cros/chromeos_cros_api.h" -#include "third_party/cros/chromeos_power.h" #include "views/controls/menu/simple_menu_model.h" #include "views/controls/menu/view_menu_delegate.h" #include "views/view.h" class Browser; +class ClockMenuButton; class NetworkMenuButton; +class PowerMenuButton; namespace views { class MenuButton; -class ImageView; } // This class is used to wrap the small informative widgets in the upper-right @@ -33,7 +32,7 @@ class StatusAreaView : public views::View, }; explicit StatusAreaView(Browser* browser); - virtual ~StatusAreaView(); + virtual ~StatusAreaView() {} void Init(); @@ -58,34 +57,20 @@ class StatusAreaView : public views::View, // views::ViewMenuDelegate implementation. virtual void RunMenu(views::View* source, const gfx::Point& pt, gfx::NativeView hwnd); - // Called whenever the battery status changes. - void PowerStatusChanged(const chromeos::PowerStatus& status); - - static void LoadCrosLibrary(); - // Called whenever the battery status changes. Dispatches to - // PowerStatusChanged() instance method. - static void PowerStatusChangedHandler( - void* object, const chromeos::PowerStatus& status); // The browser window that owns us. Browser* browser_; + ClockMenuButton* clock_view_; NetworkMenuButton* network_view_; - views::ImageView* battery_view_; + PowerMenuButton* battery_view_; views::MenuButton* menu_view_; scoped_ptr<views::SimpleMenuModel> app_menu_contents_; scoped_ptr<views::SimpleMenuModel> options_menu_contents_; scoped_ptr<views::Menu2> app_menu_menu_; - // A reference to the battery power api, to allow callbacks when the - // battery status changes. - chromeos::PowerStatusConnection power_status_connection_; static OpenTabsMode open_tabs_mode_; - // True if the library was loaded. - static bool cros_library_loaded_; - // True if there was an error loading the cros shared object. - static bool cros_library_error_; DISALLOW_COPY_AND_ASSIGN(StatusAreaView); }; |