1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SYSTEM_UNIFIED_UNIFIED_SYSTEM_TRAY_H_
#define ASH_SYSTEM_UNIFIED_UNIFIED_SYSTEM_TRAY_H_
#include <list>
#include <memory>
#include <string>
#include "ash/ash_export.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/tablet_mode_observer.h"
#include "ash/system/power/tray_power.h"
#include "ash/system/tray/tray_background_view.h"
#include "ash/system/unified/unified_system_tray_controller.h"
#include "ash/system/unified/unified_system_tray_model.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/display/display_observer.h"
namespace display {
enum class TabletState;
} // namespace display
namespace ui {
class Event;
} // namespace ui
namespace views {
class Widget;
} // namespace views
namespace ash {
class AutozoomToastController;
class CameraMicTrayItemView;
class ChannelIndicatorView;
class CurrentLocaleView;
class HotspotTrayView;
class ImeModeView;
class ManagedDeviceTrayItemView;
class NetworkTrayView;
class PrivacyScreenToastController;
class Shelf;
class TrayBubbleView;
class TrayItemView;
class TimeTrayItemView;
class UnifiedSliderBubbleController;
class UnifiedSliderView;
class UnifiedSystemTrayBubble;
// The UnifiedSystemTray is the system menu of Chromium OS, which is a clickable
// rounded rectangle typically located on the bottom right corner of the screen,
// (called the Status Area). The system tray shows multiple icons on it to
// indicate system status (e.g. time, power, etc.).
//
// Note that the Status Area refers to the parent container of the
// UnifiedSystemTray, which also includes other "trays" such as the ImeMenuTray,
// SelectToSpeakTray, VirtualKeyboardTray, etc.
//
// UnifiedSystemTrayBubble is the actual menu bubble shown above the system tray
// after the user clicks on it. The UnifiedSystemTrayBubble is created and owned
// by this class.
class ASH_EXPORT UnifiedSystemTray
: public TrayBackgroundView,
public ShelfConfig::Observer,
public UnifiedSystemTrayController::Observer,
public display::DisplayObserver,
public PowerStatus::Observer,
public TrayItemView::Observer {
METADATA_HEADER(UnifiedSystemTray, TrayBackgroundView)
public:
class Observer : public base::CheckedObserver {
public:
// Gets called when showing calendar view.
virtual void OnOpeningCalendarView() {}
// Gets called when leaving from the calendar view.
virtual void OnLeavingCalendarView() {}
// Gets called when a slider bubble is shown or closed.
virtual void OnSliderBubbleHeightChanged() {}
};
explicit UnifiedSystemTray(Shelf* shelf);
UnifiedSystemTray(const UnifiedSystemTray&) = delete;
UnifiedSystemTray& operator=(const UnifiedSystemTray&) = delete;
~UnifiedSystemTray() override;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Callback called when this is pressed.
void OnButtonPressed(const ui::Event& event);
// True if the bubble is shown. It does not include slider bubbles, and when
// they're shown it still returns false.
bool IsBubbleShown() const;
// True if a slider bubble e.g. volume slider triggered by keyboard
// accelerator is shown.
bool IsSliderBubbleShown() const;
// Gets the slider view of the slider bubble.
UnifiedSliderView* GetSliderView() const;
// True if the bubble is active.
bool IsBubbleActive() const;
// Closes all secondary bubbles (e.g. volume/brightness sliders, autozoom,
// privacy screen toast) if any are shown.
// TODO(b/279044049): Consider making autozoom and privacy screen slider
// bubbles, or have them extend a common class with sliders.
void CloseSecondaryBubbles();
// Activates the system tray bubble.
void ActivateBubble();
// Shows volume slider bubble shown at the right bottom of screen. The bubble
// is same as one shown when volume buttons on keyboard are pressed.
void ShowVolumeSliderBubble();
// Shows main bubble with audio settings detailed view.
void ShowAudioDetailedViewBubble();
// Shows main bubble with display settings detailed view.
void ShowDisplayDetailedViewBubble();
// Shows main bubble with network settings detailed view.
void ShowNetworkDetailedViewBubble();
// Return the bounds of the bubble in the screen.
gfx::Rect GetBubbleBoundsInScreen() const;
// Enable / disable UnifiedSystemTray button in status area. If the bubble is
// open when disabling, also close it.
void SetTrayEnabled(bool enabled);
// Notifies the height of the secondary bubble (e.g. Volume/Brightness
// sliders, Privacy screen/Autozoom toast) if one is showing so notification
// popups or toasts won't overlap with it. Pass 0 if no bubble is shown.
void NotifySecondaryBubbleHeight(int height);
// Called by `UnifiedSystemTrayBubble` when it is destroyed with the calendar
// view in the foreground.
void NotifyLeavingCalendarView();
// This enum is for the ChromeOS.SystemTray.FirstInteraction UMA histogram and
// should be kept in sync.
enum class FirstInteractionType {
kQuickSettings = 0,
kMessageCenter = 1,
kMaxValue = kMessageCenter,
};
// Records a metric of the first interaction with the tray bubble, i.e.
// whether it was a click/tap on the message center or quick settings.
void MaybeRecordFirstInteraction(FirstInteractionType type);
// TrayBackgroundView:
void ShowBubble() override;
void CloseBubbleInternal() override;
std::u16string GetAccessibleNameForBubble() override;
void HandleLocaleChange() override;
void HideBubble(const TrayBubbleView* bubble_view) override;
void HideBubbleWithView(const TrayBubbleView* bubble_view) override;
void ClickedOutsideBubble(const ui::LocatedEvent& event) override;
void UpdateTrayItemColor(bool is_active) override;
void UpdateLayout() override;
void UpdateAfterLoginStatusChange() override;
bool ShouldEnableExtraKeyboardAccessibility() override;
views::Widget* GetBubbleWidget() const override;
TrayBubbleView* GetBubbleView() override;
std::optional<AcceleratorAction> GetAcceleratorAction() const override;
// ShelfConfig::Observer:
void OnShelfConfigUpdated() override;
// PowerStatus::Observer:
void OnPowerStatusChanged() override;
// UnifiedSystemTrayController::Observer:
void OnOpeningCalendarView() override;
void OnTransitioningFromCalendarToMainView() override;
// display::DisplayObserver:
void OnDisplayTabletStateChanged(display::TabletState state) override;
// TrayItem::Observer:
void OnTrayItemVisibilityAboutToChange(bool target_visibility) override {}
void OnTrayItemChildViewChanged() override;
// Gets called when an action is performed on the `DateTray`.
void OnDateTrayActionPerformed(const ui::Event& event);
// Whether the bubble is currently showing the calendar view.
bool IsShowingCalendarView() const;
// Returns whether the channel indicator should be shown.
bool ShouldChannelIndicatorBeShown() const;
std::u16string GetAccessibleNameForQuickSettingsBubble();
void UpdateAccessibleName();
scoped_refptr<UnifiedSystemTrayModel> model() { return model_; }
UnifiedSystemTrayBubble* bubble() { return bubble_.get(); }
ChannelIndicatorView* channel_indicator_view() {
return channel_indicator_view_;
}
UnifiedSliderBubbleController* slider_bubble_controller() {
return slider_bubble_controller_.get();
}
CameraMicTrayItemView* mic_view() { return mic_view_; }
private:
friend class NotificationGroupingControllerTest;
friend class SystemTrayTestApi;
friend class UnifiedSystemTrayTest;
friend class PowerTrayViewTest;
friend class StatusAreaBatteryPixelTest;
friend class UnifiedSystemTrayAccessibilityTest;
friend class PrivacyScreenToastControllerTest;
// Forwarded from `UiDelegate`.
void ShowBubbleInternal();
void HideBubbleInternal();
// Adds the tray item to the the unified system tray container. An unowned
// pointer is stored in `tray_items_`.
template <typename T>
T* AddTrayItemToContainer(std::unique_ptr<T> tray_item_view);
// Destroys the `bubble_`, also handles
// removing bubble related observers.
void DestroyBubble();
// Calculate the accessible name for the tray that will be set in the
// ViewAccessibility cache.
std::u16string CalculateAccessibleName();
// Callback called when there are changes to the accessible name of child
// Views that impact the UnifiedSystemTray's accessible name.
void OnChildViewNameChanged(ax::mojom::StringAttribute attribute,
const std::optional<std::string>& name);
// Registers callbacks for child View properties that impact the tray's
// accessible properties.
void SubscribeCallbacksForAccessibility();
// The `channel_indicator_view_` can have either an image_view() or a label(),
// but not both at the same time. The existence of either impacts the
// UnifiedSystemTray's accessible name. As the lifecycle of these objects
// change, we will need to update our callbacks.
void SubscribeChannelIndicatorImageOrLabelCallbacks();
// Returns the time from `clock_for_testing_` if it is not nullptr, or time
// from base::Time::Now() otherwise.
void OverrideClockForTesting(base::Clock* test_clock);
const base::Time GetTimeNow();
// A clock that can be overridden by tests.
raw_ptr<base::Clock> clock_for_testing_ = nullptr;
std::unique_ptr<UnifiedSystemTrayBubble> bubble_;
// Model class that stores `UnifiedSystemTray`'s UI specific variables.
scoped_refptr<UnifiedSystemTrayModel> model_;
const std::unique_ptr<UnifiedSliderBubbleController>
slider_bubble_controller_;
const std::unique_ptr<PrivacyScreenToastController>
privacy_screen_toast_controller_;
std::unique_ptr<AutozoomToastController> autozoom_toast_controller_;
// Owned by the views hierarchy.
raw_ptr<CurrentLocaleView> current_locale_view_ = nullptr;
raw_ptr<ImeModeView> ime_mode_view_ = nullptr;
raw_ptr<ManagedDeviceTrayItemView> managed_device_view_ = nullptr;
raw_ptr<CameraMicTrayItemView> camera_view_ = nullptr;
raw_ptr<CameraMicTrayItemView> mic_view_ = nullptr;
raw_ptr<TimeTrayItemView> time_tray_item_view_ = nullptr;
raw_ptr<HotspotTrayView> hotspot_tray_view_ = nullptr;
raw_ptr<NetworkTrayView> network_tray_view_ = nullptr;
raw_ptr<ChannelIndicatorView> channel_indicator_view_ = nullptr;
raw_ptr<PowerTrayView> power_tray_view_ = nullptr;
// Contains all tray items views added to tray_container().
std::list<raw_ptr<TrayItemView, CtnExperimental>> tray_items_;
bool first_interaction_recorded_ = false;
base::ObserverList<Observer> observers_;
display::ScopedDisplayObserver display_observer_{this};
// Records time the QS bubble was shown. Used for metrics.
base::TimeTicks time_opened_;
base::CallbackListSubscription time_view_text_changed_subscription_;
base::CallbackListSubscription
channel_indicator_visible_changed_subscription_;
base::CallbackListSubscription
channel_indicator_image_name_changed_subscription_;
base::CallbackListSubscription channel_indicator_label_changed_subscription_;
base::CallbackListSubscription newtwork_tray_visible_changed_subscription_;
base::CallbackListSubscription
network_tray_tooltip_text_changed_subscription_;
base::CallbackListSubscription hotspot_tray_visible_changed_subscription_;
base::CallbackListSubscription
hotspot_tray_tooltip_text_changed_subscription_;
base::CallbackListSubscription managed_device_visible_changed_subscription_;
base::CallbackListSubscription
managed_device_image_tooltip_text_changed_subscription_;
base::CallbackListSubscription ime_mode_visible_changed_subscription_;
base::CallbackListSubscription ime_mode_label_name_changed_subscription_;
base::CallbackListSubscription current_locale_visible_changed_subscription_;
base::CallbackListSubscription
current_locale_label_name_changed_subscription_;
base::WeakPtrFactory<UnifiedSystemTray> weak_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_UNIFIED_UNIFIED_SYSTEM_TRAY_H_
|