blob: 937062566a31c9ae93adec41668f3018f5d8354f [file] [log] [blame] [edit]
// Copyright (c) 2012 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 "ash/system/status_area_widget.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/system/bluetooth/bluetooth_observer.h"
#include "ash/system/network/network_observer.h"
#include "ash/system/status_area_widget_delegate.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/web_notification/web_notification_tray.h"
#include "ash/volume_control_delegate.h"
#include "ash/wm/shelf_layout_manager.h"
#include "ash/wm/window_properties.h"
#include "base/i18n/time_formatting.h"
#include "base/utf_string_conversions.h"
#include "ui/aura/window.h"
#include "ui/gfx/screen.h"
namespace ash {
namespace {
class DummyVolumeControlDelegate : public VolumeControlDelegate {
public:
DummyVolumeControlDelegate() {}
virtual ~DummyVolumeControlDelegate() {}
virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE {
return true;
}
virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE {
return true;
}
virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE {
return true;
}
virtual void SetVolumePercent(double percent) OVERRIDE {
}
virtual bool IsAudioMuted() const OVERRIDE {
return true;
}
virtual void SetAudioMuted(bool muted) OVERRIDE {
}
virtual float GetVolumeLevel() const OVERRIDE {
return 0.0;
}
virtual void SetVolumeLevel(float level) OVERRIDE {
}
private:
DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate);
};
class DummySystemTrayDelegate : public SystemTrayDelegate {
public:
DummySystemTrayDelegate()
: wifi_enabled_(true),
cellular_enabled_(true),
bluetooth_enabled_(true),
caps_lock_enabled_(false),
volume_control_delegate_(
ALLOW_THIS_IN_INITIALIZER_LIST(new DummyVolumeControlDelegate)) {
}
virtual ~DummySystemTrayDelegate() {}
private:
virtual bool GetTrayVisibilityOnStartup() OVERRIDE { return true; }
// Overridden from SystemTrayDelegate:
virtual const string16 GetUserDisplayName() const OVERRIDE {
return UTF8ToUTF16("Über tray Über tray Über tray Über tray");
}
virtual const std::string GetUserEmail() const OVERRIDE {
return "über@tray";
}
virtual const gfx::ImageSkia& GetUserImage() const OVERRIDE {
return null_image_;
}
virtual user::LoginStatus GetUserLoginStatus() const OVERRIDE {
return user::LOGGED_IN_USER;
}
virtual bool SystemShouldUpgrade() const OVERRIDE {
return true;
}
virtual base::HourClockType GetHourClockType() const OVERRIDE {
return base::k24HourClock;
}
virtual PowerSupplyStatus GetPowerSupplyStatus() const OVERRIDE {
return PowerSupplyStatus();
}
virtual void RequestStatusUpdate() const OVERRIDE {
}
virtual void ShowSettings() OVERRIDE {
}
virtual void ShowDateSettings() OVERRIDE {
}
virtual void ShowNetworkSettings() OVERRIDE {
}
virtual void ShowBluetoothSettings() OVERRIDE {
}
virtual void ShowDisplaySettings() OVERRIDE {
}
virtual void ShowDriveSettings() OVERRIDE {
}
virtual void ShowIMESettings() OVERRIDE {
}
virtual void ShowHelp() OVERRIDE {
}
virtual void ShutDown() OVERRIDE {
MessageLoop::current()->Quit();
}
virtual void SignOut() OVERRIDE {
MessageLoop::current()->Quit();
}
virtual void RequestLockScreen() OVERRIDE {}
virtual void RequestRestart() OVERRIDE {}
virtual void GetAvailableBluetoothDevices(
BluetoothDeviceList* list) OVERRIDE {
}
virtual void ToggleBluetoothConnection(const std::string& address) OVERRIDE {
}
virtual void GetCurrentIME(IMEInfo* info) OVERRIDE {
}
virtual void GetAvailableIMEList(IMEInfoList* list) OVERRIDE {
}
virtual void GetCurrentIMEProperties(IMEPropertyInfoList* list) OVERRIDE {
}
virtual void SwitchIME(const std::string& ime_id) OVERRIDE {
}
virtual void ActivateIMEProperty(const std::string& key) OVERRIDE {
}
virtual void CancelDriveOperation(const FilePath&) OVERRIDE {
}
virtual void GetDriveOperationStatusList(
ash::DriveOperationStatusList*) OVERRIDE {
}
virtual void GetMostRelevantNetworkIcon(NetworkIconInfo* info,
bool large) OVERRIDE {
}
virtual void GetAvailableNetworks(
std::vector<NetworkIconInfo>* list) OVERRIDE {
}
virtual void ConnectToNetwork(const std::string& network_id) OVERRIDE {
}
virtual void GetNetworkAddresses(std::string* ip_address,
std::string* ethernet_mac_address,
std::string* wifi_mac_address) OVERRIDE {
*ip_address = "127.0.0.1";
*ethernet_mac_address = "00:11:22:33:44:55";
*wifi_mac_address = "66:77:88:99:00:11";
}
virtual void RequestNetworkScan() OVERRIDE {
}
virtual void AddBluetoothDevice() OVERRIDE {
}
virtual void ToggleAirplaneMode() OVERRIDE {
}
virtual void ToggleWifi() OVERRIDE {
wifi_enabled_ = !wifi_enabled_;
ash::NetworkObserver* observer =
ash::Shell::GetInstance()->system_tray()->network_observer();
if (observer) {
ash::NetworkIconInfo info;
observer->OnNetworkRefresh(info);
}
}
virtual void ToggleMobile() OVERRIDE {
cellular_enabled_ = !cellular_enabled_;
ash::NetworkObserver* observer =
ash::Shell::GetInstance()->system_tray()->network_observer();
if (observer) {
ash::NetworkIconInfo info;
observer->OnNetworkRefresh(info);
}
}
virtual void ToggleBluetooth() OVERRIDE {
bluetooth_enabled_ = !bluetooth_enabled_;
ash::BluetoothObserver* observer =
ash::Shell::GetInstance()->system_tray()->bluetooth_observer();
if (observer)
observer->OnBluetoothRefresh();
}
virtual void ShowOtherWifi() OVERRIDE {
}
virtual void ShowOtherCellular() OVERRIDE {
}
virtual bool IsNetworkConnected() OVERRIDE {
return true;
}
virtual bool GetWifiAvailable() OVERRIDE {
return true;
}
virtual bool GetMobileAvailable() OVERRIDE {
return true;
}
virtual bool GetBluetoothAvailable() OVERRIDE {
return true;
}
virtual bool GetWifiEnabled() OVERRIDE {
return wifi_enabled_;
}
virtual bool GetMobileEnabled() OVERRIDE {
return cellular_enabled_;
}
virtual bool GetBluetoothEnabled() OVERRIDE {
return bluetooth_enabled_;
}
virtual bool GetMobileScanSupported() OVERRIDE {
return true;
}
virtual bool GetCellularCarrierInfo(std::string* carrier_id,
std::string* topup_url,
std::string* setup_url) OVERRIDE {
return false;
}
virtual void ShowCellularURL(const std::string& url) OVERRIDE {
}
virtual void ChangeProxySettings() OVERRIDE {
}
virtual VolumeControlDelegate* GetVolumeControlDelegate() const OVERRIDE {
return volume_control_delegate_.get();
}
virtual void SetVolumeControlDelegate(
scoped_ptr<VolumeControlDelegate> delegate) OVERRIDE {
volume_control_delegate_.swap(delegate);
}
bool wifi_enabled_;
bool cellular_enabled_;
bool bluetooth_enabled_;
bool caps_lock_enabled_;
gfx::ImageSkia null_image_;
scoped_ptr<VolumeControlDelegate> volume_control_delegate_;
DISALLOW_COPY_AND_ASSIGN(DummySystemTrayDelegate);
};
} // namespace
namespace internal {
StatusAreaWidget::StatusAreaWidget()
: status_area_widget_delegate_(new internal::StatusAreaWidgetDelegate),
system_tray_(NULL),
web_notification_tray_(NULL),
login_status_(user::LOGGED_IN_NONE) {
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.delegate = status_area_widget_delegate_;
params.parent =
Shell::GetPrimaryRootWindowController()->GetContainer(
ash::internal::kShellWindowId_StatusContainer);
params.transparent = true;
Init(params);
set_focus_on_creation(false);
SetContentsView(status_area_widget_delegate_);
GetNativeView()->SetName("StatusAreaWidget");
GetNativeView()->SetProperty(internal::kStayInSameRootWindowKey, true);
}
StatusAreaWidget::~StatusAreaWidget() {
}
void StatusAreaWidget::CreateTrayViews(ShellDelegate* shell_delegate) {
AddSystemTray(shell_delegate);
AddWebNotificationTray();
// Initialize() must be called after all trays have been created.
if (system_tray_)
system_tray_->Initialize();
if (web_notification_tray_)
web_notification_tray_->Initialize();
UpdateAfterLoginStatusChange(system_tray_delegate_->GetUserLoginStatus());
}
void StatusAreaWidget::Shutdown() {
// Destroy the trays early, causing them to be removed from the view
// hierarchy. Do not used scoped pointers since we don't want to destroy them
// in the destructor if Shutdown() is not called (e.g. in tests).
system_tray_delegate_.reset();
delete web_notification_tray_;
web_notification_tray_ = NULL;
delete system_tray_;
system_tray_ = NULL;
}
bool StatusAreaWidget::ShouldShowLauncher() const {
if ((system_tray_ && system_tray_->HasSystemBubble()) ||
(web_notification_tray_ &&
web_notification_tray_->IsMessageCenterBubbleVisible()))
return true;
if (!Shell::GetInstance()->shelf()->IsVisible())
return false;
// If the launcher is currently visible, don't hide the launcher if the mouse
// is in any of the notification bubbles.
return (system_tray_ && system_tray_->IsMouseInNotificationBubble()) ||
(web_notification_tray_ &&
web_notification_tray_->IsMouseInNotificationBubble());
}
bool StatusAreaWidget::IsMessageBubbleShown() const {
return ((system_tray_ && system_tray_->IsAnyBubbleVisible()) ||
(web_notification_tray_ &&
web_notification_tray_->IsMessageCenterBubbleVisible()));
}
void StatusAreaWidget::AddSystemTray(ShellDelegate* shell_delegate) {
system_tray_ = new SystemTray(this);
status_area_widget_delegate_->AddTray(system_tray_);
if (shell_delegate) {
system_tray_delegate_.reset(
shell_delegate->CreateSystemTrayDelegate(system_tray_));
}
if (!system_tray_delegate_.get())
system_tray_delegate_.reset(new DummySystemTrayDelegate());
}
void StatusAreaWidget::AddWebNotificationTray() {
web_notification_tray_ = new WebNotificationTray(this);
status_area_widget_delegate_->AddTray(web_notification_tray_);
}
void StatusAreaWidget::SetShelfAlignment(ShelfAlignment alignment) {
status_area_widget_delegate_->set_alignment(alignment);
if (system_tray_)
system_tray_->SetShelfAlignment(alignment);
if (web_notification_tray_)
web_notification_tray_->SetShelfAlignment(alignment);
status_area_widget_delegate_->UpdateLayout();
}
void StatusAreaWidget::SetPaintsBackground(
bool value,
internal::BackgroundAnimator::ChangeType change_type) {
if (system_tray_)
system_tray_->SetPaintsBackground(value, change_type);
if (web_notification_tray_)
web_notification_tray_->SetPaintsBackground(value, change_type);
}
void StatusAreaWidget::SetHideWebNotifications(bool hide) {
if (web_notification_tray_)
web_notification_tray_->SetHidePopupBubble(hide);
}
void StatusAreaWidget::SetHideSystemNotifications(bool hide) {
if (system_tray_)
system_tray_->SetHideNotifications(hide);
}
bool StatusAreaWidget::ShouldShowWebNotifications() {
return !(system_tray_ && system_tray_->IsAnyBubbleVisible());
}
void StatusAreaWidget::UpdateAfterLoginStatusChange(
user::LoginStatus login_status) {
if (login_status_ == login_status)
return;
login_status_ = login_status;
if (system_tray_)
system_tray_->UpdateAfterLoginStatusChange(login_status);
if (web_notification_tray_)
web_notification_tray_->UpdateAfterLoginStatusChange(login_status);
}
} // namespace internal
} // namespace ash