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

ash / system / toast / toast_manager_impl.h [blame]

// Copyright 2016 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_TOAST_TOAST_MANAGER_IMPL_H_
#define ASH_SYSTEM_TOAST_TOAST_MANAGER_IMPL_H_

#include <memory>
#include <string>

#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/system/toast_data.h"
#include "ash/public/cpp/system/toast_manager.h"
#include "ash/shell.h"
#include "ash/shell_observer.h"
#include "ash/system/toast/toast_overlay.h"
#include "base/containers/circular_deque.h"
#include "base/memory/weak_ptr.h"

namespace aura {
class Window;
}

namespace ash {

class ScopedToastPause;

namespace eche_app {
class LaunchAppHelperTest;
}

namespace video_conference {
class VideoConferenceIntegrationTest;
}

// Class managing toast requests.
class ASH_EXPORT ToastManagerImpl : public ToastManager,
                                    public ToastOverlay::Delegate,
                                    public SessionObserver,
                                    public ShellObserver {
 public:
  ToastManagerImpl();

  ToastManagerImpl(const ToastManagerImpl&) = delete;
  ToastManagerImpl& operator=(const ToastManagerImpl&) = delete;

  ~ToastManagerImpl() override;

  // ToastManager:
  void Show(ToastData data) override;
  void Cancel(std::string_view id) override;
  bool RequestFocusOnActiveToastButton(std::string_view id) override;
  bool IsToastShown(std::string_view id) const override;
  bool IsToastButtonFocused(std::string_view id) const override;
  std::unique_ptr<ScopedToastPause> CreateScopedPause() override;

  // ToastOverlay::Delegate:
  void CloseToast() override;
  void OnToastHoverStateChanged(bool is_hovering) override;

  // SessionObserver:
  void OnSessionStateChanged(session_manager::SessionState state) override;

 private:
  class PausableTimer;
  friend class AutoConnectNotifierTest;
  friend class BluetoothNotificationControllerTest;
  friend class DesksTestApi;
  friend class LoginScreenControllerTest;
  friend class ToastManagerImplTest;
  friend class BatterySaverControllerTest;
  friend class BatteryNotificationTest;
  friend class eche_app::LaunchAppHelperTest;
  friend class video_conference::VideoConferenceIntegrationTest;

  void ShowLatest();

  // Creates a new toast overlay to be displayed on the designated
  // `root_window`.
  void CreateToastOverlayForRoot(aura::Window* root_window);

  // Unshows all existing toast instances in `root_window_to_overlay_`.
  void CloseAllToastsWithAnimation();

  // Resets all existing toast instances in `root_window_to_overlay_`,
  // effectively closing them without animation.
  void CloseAllToastsWithoutAnimation();

  // Checks whether any values in `root_window_to_overlay_` are not empty.
  bool HasActiveToasts() const;

  ToastOverlay* GetCurrentOverlayForTesting(
      aura::Window* root_window = Shell::GetRootWindowForNewWindows());

  int serial_for_testing() const { return serial_; }
  void ResetSerialForTesting() { serial_ = 0; }

  // ShellObserver:
  void OnRootWindowAdded(aura::Window* root_window) override;
  void OnRootWindowWillShutdown(aura::Window* root_window) override;

  // ToastManager:
  void Pause() override;
  void Resume() override;

  // Used to destroy the currently running toast if its duration is not
  // infinite. Also allows us to persist the toast on hover by pausing this
  // timer when a toast instance is being hovered by the mouse.
  std::unique_ptr<PausableTimer> current_toast_expiration_timer_;

  int serial_ = 0;
  bool locked_;
  base::circular_deque<ToastData> queue_;

  // Tracks active toast overlays and their corresponding root windows.
  base::flat_map<aura::Window*, std::unique_ptr<ToastOverlay>>
      root_window_to_overlay_;

  // Keeps track of the number of `ScopedToastPause`.
  int pause_counter_ = 0;

  // Data of the toast which is currently shown. Empty if no toast is visible.
  // Destroying a `ToastData` can reentrantly access other fields, so ensure it
  // is destroyed before other data fields to prevent use-after-dtor issues when
  // destroying `this`.
  std::optional<ToastData> current_toast_data_;

  ScopedSessionObserver scoped_session_observer_{this};
  base::WeakPtrFactory<ToastManagerImpl> weak_ptr_factory_{this};
};

}  // namespace ash

#endif  // ASH_SYSTEM_TOAST_TOAST_MANAGER_IMPL_H_