15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_switches.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/metrics/user_metrics_recorder.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/audio/tray_audio.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/bluetooth/tray_bluetooth.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/date/tray_date.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/ime/tray_ime.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/status_area_widget.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_item.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_bubble_wrapper.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray_accessibility.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray_update.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/user/login_status.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/user/tray_user.h" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/system/user/tray_user_separator.h" 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/system/web_notification/web_notification_tray.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h" 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/border.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/chromeos/audio/tray_audio_chromeos.h" 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/system/chromeos/brightness/tray_brightness.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/chromeos/enterprise/tray_enterprise.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/chromeos/network/tray_network.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/chromeos/network/tray_sms.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/chromeos/network/tray_vpn.h" 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ash/system/chromeos/power/power_status.h" 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/system/chromeos/power/tray_power.h" 53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/chromeos/rotation/tray_rotation_lock.h" 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/system/chromeos/screen_security/screen_capture_tray_item.h" 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/system/chromeos/screen_security/screen_share_tray_item.h" 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/chromeos/session/tray_session_length_limit.h" 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/system/chromeos/settings/tray_settings.h" 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ash/system/chromeos/supervised/tray_supervised_user.h" 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/chromeos/tray_caps_lock.h" 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/chromeos/tray_display.h" 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/system/chromeos/tray_tracing.h" 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/system/tray/media_security/multi_profile_media_tray_item.h" 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/message_center/message_center.h" 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_WIN) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/win/audio/tray_audio_win.h" 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/audio/win/core_audio_util_win.h" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::TrayBubbleView; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The minimum width of the system tray menu width. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinimumSystemTrayMenuWidth = 300; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class to initialize and manage the SystemTrayBubble and TrayBubbleWrapper 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instances for a bubble. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SystemBubbleWrapper { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes ownership of |bubble|. 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch explicit SystemBubbleWrapper(SystemTrayBubble* bubble) 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : bubble_(bubble), is_persistent_(false) {} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the bubble view and creates |bubble_wrapper_|. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitView(TrayBackgroundView* tray, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* anchor, 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) TrayBubbleView::InitParams* init_params, 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_persistent) { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(anchor); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user::LoginStatus login_status = 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_->InitView(anchor, login_status, init_params); 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bubble_wrapper_.reset(new TrayBubbleWrapper(tray, bubble_->bubble_view())); 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The system bubble should not have an arrow. 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bubble_->bubble_view()->SetArrowPaintType( 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::BubbleBorder::PAINT_NONE); 981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) is_persistent_ = is_persistent; 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If ChromeVox is enabled, focus the default item if no item is focused. 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (Shell::GetInstance()->accessibility_delegate()-> 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IsSpokenFeedbackEnabled()) { 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bubble_->FocusDefaultIfNeeded(); 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convenience accessors: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble* bubble() const { return bubble_.get(); } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble::BubbleType bubble_type() const { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bubble_->bubble_type(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_persistent() const { return is_persistent_; } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<SystemTrayBubble> bubble_; 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<TrayBubbleWrapper> bubble_wrapper_; 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool is_persistent_; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SystemBubbleWrapper); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SystemTray 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochSystemTray::SystemTray(StatusAreaWidget* status_area_widget) 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : TrayBackgroundView(status_area_widget), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items_(), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_bubble_height_(0), 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hide_notifications_(false), 131558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch full_system_tray_menu_(false), 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) tray_accessibility_(NULL), 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) tray_date_(NULL) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetContentsBackground(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SystemTray::~SystemTray() { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy any child views that might have back pointers before ~View(). 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_.reset(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_.reset(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != items_.end(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->DestroyTrayView(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemTray::InitializeTrayItems(SystemTrayDelegate* delegate) { 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TrayBackgroundView::Initialize(); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateItems(delegate); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemTray::CreateItems(SystemTrayDelegate* delegate) { 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_WIN) 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Create user items for each possible user. 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ash::Shell* shell = ash::Shell::GetInstance(); 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int maximum_user_profiles = 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers(); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (int i = 0; i < maximum_user_profiles; i++) 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayUser(this, i)); 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (maximum_user_profiles > 1) { 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add a special double line separator between users and the rest of the 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // menu if more then one user is logged in. 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayUserSeparator(this)); 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tray_accessibility_ = new TrayAccessibility(this); 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tray_date_ = new TrayDate(this); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AddTrayItem(new TraySessionLengthLimit(this)); 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayEnterprise(this)); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AddTrayItem(new TraySupervisedUser(this)); 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayIME(this)); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddTrayItem(tray_accessibility_); 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayTracing(this)); 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayPower(this, message_center::MessageCenter::Get())); 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayNetwork(this)); 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayVPN(this)); 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TraySms(this)); 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayBluetooth(this)); 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayDisplay(this)); 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) screen_capture_tray_item_ = new ScreenCaptureTrayItem(this); 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddTrayItem(screen_capture_tray_item_); 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) screen_share_tray_item_ = new ScreenShareTrayItem(this); 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AddTrayItem(screen_share_tray_item_); 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AddTrayItem(new MultiProfileMediaTrayItem(this)); 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayAudioChromeOs(this)); 191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayBrightness(this)); 192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayCapsLock(this)); 193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TraySettings(this)); 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayUpdate(this)); 195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddTrayItem(new TrayRotationLock(this)); 1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AddTrayItem(tray_date_); 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_WIN) 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddTrayItem(tray_accessibility_); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (media::CoreAudioUtil::IsSupported()) 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayAudioWin(this)); 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayUpdate(this)); 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AddTrayItem(tray_date_); 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_LINUX) 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayIME(this)); 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddTrayItem(tray_accessibility_); 206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayBluetooth(this)); 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AddTrayItem(new TrayUpdate(this)); 2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AddTrayItem(tray_date_); 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetVisible(ash::Shell::GetInstance()->system_tray_delegate()-> 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTrayVisibilityOnStartup()); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::AddTrayItem(SystemTrayItem* item) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items_.push_back(item); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* tray_item = item->CreateTrayView(delegate->GetUserLoginStatus()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->UpdateAfterShelfAlignmentChange(shelf_alignment()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tray_item) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tray_container()->AddChildViewAt(tray_item, 0); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tray_item_map_[item] = tray_item; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::RemoveTrayItem(SystemTrayItem* item) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst std::vector<SystemTrayItem*>& SystemTray::GetTrayItems() const { 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return items_.get(); 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::ShowDefaultView(BubbleCreationType creation_type) { 2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ShowDefaultViewWithOffset( 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) creation_type, 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) TrayBubbleView::InitParams::kArrowDefaultOffset, 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) false); 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SystemTray::ShowPersistentDefaultView() { 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShowItems(items_.get(), 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BUBBLE_CREATE_NEW, 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TrayBubbleView::InitParams::kArrowDefaultOffset, 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) true); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::ShowDetailedView(SystemTrayItem* item, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int close_delay, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool activate, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BubbleCreationType creation_type) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SystemTrayItem*> items; 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The detailed view with timeout means a UI to show the current system state, 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // like the audio level or brightness. Such UI should behave as persistent and 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // keep its own logic for the appearance. 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool persistent = ( 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !activate && close_delay > 0 && creation_type == BUBBLE_CREATE_NEW); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.push_back(item); 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ShowItems( 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch items, true, activate, creation_type, GetTrayXOffset(item), persistent); 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (system_bubble_) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_bubble_->bubble()->StartAutoCloseTimer(close_delay); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::SetDetailedViewCloseDelay(int close_delay) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasSystemBubbleType(SystemTrayBubble::BUBBLE_TYPE_DETAILED)) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->StartAutoCloseTimer(close_delay); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::HideDetailedView(SystemTrayItem* item) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item != detailed_item_) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroySystemBubble(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNotificationBubble(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::ShowNotificationView(SystemTrayItem* item) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (std::find(notification_items_.begin(), notification_items_.end(), item) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) != notification_items_.end()) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_items_.push_back(item); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNotificationBubble(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::HideNotificationView(SystemTrayItem* item) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SystemTrayItem*>::iterator found_iter = 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(notification_items_.begin(), notification_items_.end(), item); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_iter == notification_items_.end()) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_items_.erase(found_iter); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only update the notification bubble if visible (i.e. don't create one). 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (notification_bubble_) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNotificationBubble(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroySystemBubble(); 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UpdateNotificationBubble(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != items_.end(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->UpdateAfterLoginStatusChange(login_status); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Items default to SHELF_ALIGNMENT_BOTTOM. Update them if the initial 3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // position of the shelf differs. 3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (shelf_alignment() != SHELF_ALIGNMENT_BOTTOM) 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UpdateAfterShelfAlignmentChange(shelf_alignment()); 3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetVisible(true); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<SystemTrayItem*>::iterator it = items_.begin(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != items_.end(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->UpdateAfterShelfAlignmentChange(alignment); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::SetHideNotifications(bool hide_notifications) { 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (notification_bubble_) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_->bubble()->SetVisible(!hide_notifications); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hide_notifications_ = hide_notifications; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SystemTray::ShouldShowShelf() const { 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return system_bubble_.get() && system_bubble_->bubble()->ShouldShowShelf(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SystemTray::HasSystemBubble() const { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return system_bubble_.get() != NULL; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SystemTray::HasNotificationBubble() const { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return notification_bubble_.get() != NULL; 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 346c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochSystemTrayBubble* SystemTray::GetSystemBubble() { 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!system_bubble_) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return system_bubble_->bubble(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SystemTray::IsAnyBubbleVisible() const { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((system_bubble_.get() && 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->IsVisible()) || 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (notification_bubble_.get() && 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_->bubble()->IsVisible())); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SystemTray::IsMouseInNotificationBubble() const { 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!notification_bubble_) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notification_bubble_->bubble_view()->GetBoundsInScreen().Contains( 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetScreen()->GetCursorScreenPoint()); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool SystemTray::CloseSystemBubble() const { 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!system_bubble_) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->Close(); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)views::View* SystemTray::GetHelpButtonView() const { 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return tray_date_->GetHelpButtonView(); 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SystemTray::CloseNotificationBubbleForTest() const { 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!notification_bubble_) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) notification_bubble_->bubble()->Close(); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Private methods. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SystemTray::HasSystemBubbleType(SystemTrayBubble::BubbleType type) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type != SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return system_bubble_.get() && system_bubble_->bubble_type() == type; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::DestroySystemBubble() { 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CloseSystemBubbleAndDeactivateSystemTray(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) detailed_item_ = NULL; 394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateWebNotifications(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::DestroyNotificationBubble() { 398558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (notification_bubble_) { 399558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch notification_bubble_.reset(); 400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateWebNotifications(); 401558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::string16 SystemTray::GetAccessibleNameForTray() { 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::string16 time = GetAccessibleTimeString(base::Time::Now()); 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::string16 battery = base::ASCIIToUTF16(""); 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS) 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) battery = PowerStatus::Get()->GetAccessibleNameString(false); 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return l10n_util::GetStringFUTF16( 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IDS_ASH_STATUS_TRAY_ACCESSIBLE_DESCRIPTION, time, battery); 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SystemTray::GetTrayXOffset(SystemTrayItem* item) const { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't attempt to align the arrow if the shelf is on the left or right. 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (shelf_alignment() != SHELF_ALIGNMENT_BOTTOM && 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shelf_alignment() != SHELF_ALIGNMENT_TOP) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TrayBubbleView::InitParams::kArrowDefaultOffset; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<SystemTrayItem*, views::View*>::const_iterator it = 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tray_item_map_.find(item); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == tray_item_map_.end()) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TrayBubbleView::InitParams::kArrowDefaultOffset; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const views::View* item_view = it->second; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item_view->bounds().IsEmpty()) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The bounds of item could be still empty if it does not have a visible 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tray view. In that case, use the default (minimum) offset. 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TrayBubbleView::InitParams::kArrowDefaultOffset; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point point(item_view->width() / 2, 0); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPointToWidget(item_view, &point); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return point.x(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::ShowDefaultViewWithOffset(BubbleCreationType creation_type, 4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int arrow_offset, 4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool persistent) { 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (creation_type != BUBBLE_USE_EXISTING) { 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Shell::GetInstance()->metrics()->RecordUserMetricsAction( 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::UMA_STATUS_AREA_MENU_OPENED); 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ShowItems(items_.get(), false, true, creation_type, arrow_offset, persistent); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool detailed, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_activate, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BubbleCreationType creation_type, 4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int arrow_offset, 4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool persistent) { 4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // No system tray bubbles in kiosk mode. 4547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() == 4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ash::user::LOGGED_IN_KIOSK_APP) { 4567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy any existing bubble and create a new one. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble::BubbleType bubble_type = detailed ? 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble::BUBBLE_TYPE_DETAILED : 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble::BUBBLE_TYPE_DEFAULT; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy the notification bubble here so that it doesn't get rebuilt 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // while we add items to the main bubble_ (e.g. in HideNotificationView). 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_.reset(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (system_bubble_.get() && creation_type == BUBBLE_USE_EXISTING) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->UpdateView(items, bubble_type); 469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If ChromeVox is enabled, focus the default item if no item is focused. 470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (Shell::GetInstance()->accessibility_delegate()-> 471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IsSpokenFeedbackEnabled()) { 472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) system_bubble_->bubble()->FocusDefaultIfNeeded(); 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 475558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Remember if the menu is a single property (like e.g. volume) or the 476558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // full tray menu. Note that in case of the |BUBBLE_USE_EXISTING| case 477558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // above, |full_system_tray_menu_| does not get changed since the fact that 478558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // the menu is full (or not) doesn't change even if a "single property" 479558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // (like network) replaces most of the menu. 480558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch full_system_tray_menu_ = items.size() > 1; 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The menu width is fixed, and it is a per language setting. 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int menu_width = std::max(kMinimumSystemTrayMenuWidth, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->system_tray_delegate()->GetSystemTrayMenuWidth()); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrayBubbleView::InitParams init_params(TrayBubbleView::ANCHOR_TYPE_TRAY, 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAnchorAlignment(), 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_width, 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kTrayPopupMaxWidth); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.can_activate = can_activate; 490a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch init_params.first_item_has_no_margin = true; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (detailed) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the case where a volume control or brightness control bubble 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is created. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.max_height = default_bubble_height_; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.arrow_color = kBackgroundColor; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.arrow_color = kHeaderBackgroundColor; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.arrow_offset = arrow_offset; 5001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (bubble_type == SystemTrayBubble::BUBBLE_TYPE_DEFAULT) 5011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) init_params.close_on_deactivate = !persistent; 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For Volume and Brightness we don't want to show an arrow when 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // they are shown in a bubble by themselves. 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.arrow_paint_type = views::BubbleBorder::PAINT_NORMAL; 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (items.size() == 1 && items[0]->ShouldHideArrow()) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.arrow_paint_type = views::BubbleBorder::PAINT_TRANSPARENT; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble* bubble = new SystemTrayBubble(this, items, bubble_type); 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch system_bubble_.reset(new SystemBubbleWrapper(bubble)); 5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) system_bubble_->InitView(this, tray_container(), &init_params, persistent); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save height of default view for creating detailed views directly. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!detailed) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_bubble_height_ = system_bubble_->bubble_view()->height(); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (detailed && items.size() > 0) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) detailed_item_ = items[0]; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) detailed_item_ = NULL; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNotificationBubble(); // State changed, re-create notifications. 521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!notification_bubble_) 522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateWebNotifications(); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetShelfLayoutManager()->UpdateAutoHideState(); 52458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 52558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // When we show the system menu in our alternate shelf layout, we need to 52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // tint the background. 52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (full_system_tray_menu_) 52858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SetDrawBackgroundAsActive(true); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::UpdateNotificationBubble() { 532bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Only show the notification bubble if we have notifications. 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (notification_items_.empty()) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroyNotificationBubble(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy the existing bubble before constructing a new one. 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_.reset(); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTrayBubble* notification_bubble; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) notification_bubble = new SystemTrayBubble( 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, notification_items_, SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* anchor; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrayBubbleView::AnchorType anchor_type; 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Tray items might want to show notifications while we are creating and 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // initializing the |system_bubble_| - but it might not be fully initialized 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // when coming here - this would produce a crashed like crbug.com/247416. 547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // As such we check the existence of the widget here. 548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (system_bubble_.get() && 549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) system_bubble_->bubble_view() && 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) system_bubble_->bubble_view()->GetWidget()) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor = system_bubble_->bubble_view(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_type = TrayBubbleView::ANCHOR_TYPE_BUBBLE; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor = tray_container(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anchor_type = TrayBubbleView::ANCHOR_TYPE_TRAY; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrayBubbleView::InitParams init_params(anchor_type, 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAnchorAlignment(), 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kTrayPopupMinWidth, 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kTrayPopupMaxWidth); 561a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch init_params.first_item_has_no_margin = true; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.arrow_color = kBackgroundColor; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.arrow_offset = GetTrayXOffset(notification_items_[0]); 564c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch notification_bubble_.reset(new SystemBubbleWrapper(notification_bubble)); 5651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) notification_bubble_->InitView(this, anchor, &init_params, false); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (notification_bubble->bubble_view()->child_count() == 0) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is possible that none of the items generated actual notifications. 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroyNotificationBubble(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hide_notifications_) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble->SetVisible(false); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UpdateWebNotifications(); 576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SystemTray::UpdateWebNotifications() { 579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TrayBubbleView* bubble_view = NULL; 580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (notification_bubble_) 581a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bubble_view = notification_bubble_->bubble_view(); 582a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) else if (system_bubble_) 583a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bubble_view = system_bubble_->bubble_view(); 584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int height = 0; 586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (bubble_view) { 587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow( 588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bubble_view->GetWidget()->GetNativeView()).work_area(); 589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetShelfLayoutManager()->GetAlignment() != SHELF_ALIGNMENT_TOP) { 590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) height = std::max( 591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 0, work_area.height() - bubble_view->GetBoundsInScreen().y()); 592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) height = std::max( 594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 0, bubble_view->GetBoundsInScreen().bottom() - work_area.y()); 595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status_area_widget()->web_notification_tray()->SetSystemTrayHeight(height); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::string16 SystemTray::GetAccessibleTimeString( 6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Time& now) const { 6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::HourClockType hour_type = 6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ash::Shell::GetInstance()->system_tray_delegate()->GetHourClockType(); 6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return base::TimeFormatTimeOfDayWithHourClockType( 6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) now, hour_type, base::kKeepAmPm); 6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::SetShelfAlignment(ShelfAlignment alignment) { 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (alignment == shelf_alignment()) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 611c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TrayBackgroundView::SetShelfAlignment(alignment); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateAfterShelfAlignmentChange(alignment); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy any existing bubble so that it is rebuilt correctly. 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CloseSystemBubbleAndDeactivateSystemTray(); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rebuild any notification bubble. 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (notification_bubble_) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_.reset(); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNotificationBubble(); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::AnchorUpdated() { 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (notification_bubble_) { 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_->bubble_view()->UpdateBubble(); 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure that the notification buble is above the shelf/status area. 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_bubble_->bubble_view()->GetWidget()->StackAtTop(); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateBubbleViewArrow(notification_bubble_->bubble_view()); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (system_bubble_) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble_view()->UpdateBubble(); 631a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch UpdateBubbleViewArrow(system_bubble_->bubble_view()); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SystemTray::BubbleResized(const TrayBubbleView* bubble_view) { 636d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UpdateWebNotifications(); 637d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 638d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::HideBubbleWithView(const TrayBubbleView* bubble_view) { 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (system_bubble_.get() && bubble_view == system_bubble_->bubble_view()) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroySystemBubble(); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNotificationBubble(); // State changed, re-create notifications. 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetShelfLayoutManager()->UpdateAutoHideState(); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (notification_bubble_.get() && 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bubble_view == notification_bubble_->bubble_view()) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroyNotificationBubble(); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SystemTray::ClickedOutsideBubble() { 6511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!system_bubble_ || system_bubble_->is_persistent()) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HideBubbleWithView(system_bubble_->bubble_view()); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::BubbleViewDestroyed() { 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (system_bubble_) { 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->DestroyItemViews(); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->BubbleViewDestroyed(); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::OnMouseEnteredView() { 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (system_bubble_) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->StopAutoCloseTimer(); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::OnMouseExitedView() { 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (system_bubble_) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->RestartAutoCloseTimer(); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 SystemTray::GetAccessibleNameForBubble() { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetAccessibleNameForTray(); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect SystemTray::GetAnchorRect( 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* anchor_widget, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrayBubbleView::AnchorType anchor_type, 681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TrayBubbleView::AnchorAlignment anchor_alignment) const { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetBubbleAnchorRect(anchor_widget, anchor_type, anchor_alignment); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SystemTray::HideBubble(const TrayBubbleView* bubble_view) { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HideBubbleWithView(bubble_view); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)views::View* SystemTray::GetTrayItemViewForTest(SystemTrayItem* item) { 6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::map<SystemTrayItem*, views::View*>::iterator it = 6914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tray_item_map_.find(item); 6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return it == tray_item_map_.end() ? NULL : it->second; 6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 695c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTrayDate* SystemTray::GetTrayDateForTesting() const { return tray_date_; } 6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SystemTray::PerformAction(const ui::Event& event) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're already showing the default view, hide it; otherwise, show it 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (and hide any popup that's currently shown). 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasSystemBubbleType(SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) { 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_bubble_->bubble()->Close(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int arrow_offset = TrayBubbleView::InitParams::kArrowDefaultOffset; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.IsMouseEvent() || event.type() == ui::ET_GESTURE_TAP) { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::LocatedEvent& located_event = 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const ui::LocatedEvent&>(event); 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shelf_alignment() == SHELF_ALIGNMENT_TOP) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point point(located_event.x(), 0); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPointToWidget(this, &point); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arrow_offset = point.x(); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ShowDefaultViewWithOffset(BUBBLE_CREATE_NEW, arrow_offset, false); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SystemTray::CloseSystemBubbleAndDeactivateSystemTray() { 7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) system_bubble_.reset(); 7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // When closing a system bubble with the alternate shelf layout, we need to 7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // turn off the active tinting of the shelf. 7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (full_system_tray_menu_) { 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetDrawBackgroundAsActive(false); 7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) full_system_tray_menu_ = false; 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 730