1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ASH_DISPLAY_RESOLUTION_NOTIFICATION_CONTROLLER_H_
6 #define ASH_DISPLAY_RESOLUTION_NOTIFICATION_CONTROLLER_H_
7 
8 #include <stdint.h>
9 
10 #include "ash/ash_export.h"
11 #include "ash/display/display_change_dialog.h"
12 #include "ash/display/window_tree_host_manager.h"
13 #include "ash/public/mojom/cros_display_config.mojom.h"
14 #include "base/callback.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/macros.h"
17 #include "base/memory/weak_ptr.h"
18 #include "ui/display/display_observer.h"
19 #include "ui/gfx/geometry/size.h"
20 
21 namespace ash {
22 
23 FORWARD_DECLARE_TEST(DisplayPrefsTest, PreventStore);
24 
25 // A class which manages the dialog displayed to notify the user that
26 // the display configuration has been changed.
27 class ASH_EXPORT ResolutionNotificationController
28     : public display::DisplayObserver,
29       public WindowTreeHostManager::Observer {
30  public:
31   ResolutionNotificationController();
32   ~ResolutionNotificationController() override;
33 
34   // If |display_id| is not the internal display and |source| is |kSourceUser|
35   // (which means user initiated the change), Prepare a resolution change
36   // notification for |display_id| from |old_resolution| to |new_resolution|,
37   // which offers a button to revert the change in case something goes wrong.
38   // The dialog is not dismissed by the user, the change is reverted.
39   //
40   // Then call DisplayManager::SetDisplayMode() to apply the resolution change,
41   // and return the result; true if success, false otherwise.
42   // In case SetDisplayMode() fails, the prepared notification will be
43   // discarded.
44   //
45   // If |display_id| is the internal display or |source| is |kSourcePolicy|, the
46   // resolution change is applied directly without preparing the confirm/revert
47   // notification (this kind of notification is only useful for external
48   // displays).
49   //
50   // This method does not create a notification itself. The notification will be
51   // created the next OnDisplayConfigurationChanged(), which will be called
52   // asynchronously after the resolution change is requested by this method.
53   //
54   // |accept_callback| will be called when the user accepts the resoltion change
55   // by closing the notification bubble or clicking on the accept button (if
56   // any).
57   bool PrepareNotificationAndSetDisplayMode(
58       int64_t display_id,
59       const display::ManagedDisplayMode& old_resolution,
60       const display::ManagedDisplayMode& new_resolution,
61       mojom::DisplayConfigSource source,
62       base::OnceClosure accept_callback) WARN_UNUSED_RESULT;
63 
dialog_for_testing()64   DisplayChangeDialog* dialog_for_testing() const {
65     return confirmation_dialog_.get();
66   }
67 
68  private:
69   friend class ResolutionNotificationControllerTest;
70   FRIEND_TEST_ALL_PREFIXES(ResolutionNotificationControllerTest, Timeout);
71   FRIEND_TEST_ALL_PREFIXES(DisplayPrefsTest, PreventStore);
72 
73   // A struct to bundle the data for a single resolution change.
74   struct ResolutionChangeInfo;
75 
76   // Create a new modal dialog, or replace the dialog if it already exists.
77   void CreateOrReplaceModalDialog();
78 
79   // Called when the user accepts the display resolution change. Set
80   // |close_notification| to true when the notification should be removed.
81   void AcceptResolutionChange();
82 
83   // Called when the user wants to revert the display resolution change.
84   void RevertResolutionChange(bool display_was_removed);
85 
86   // display::DisplayObserver overrides:
87   void OnDisplayRemoved(const display::Display& old_display) override;
88 
89   // WindowTreeHostManager::Observer overrides:
90   void OnDisplayConfigurationChanged() override;
91 
92   std::unique_ptr<ResolutionChangeInfo> change_info_;
93 
94   base::WeakPtr<DisplayChangeDialog> confirmation_dialog_;
95 
96   base::WeakPtrFactory<ResolutionNotificationController> weak_factory_{this};
97 
98   DISALLOW_COPY_AND_ASSIGN(ResolutionNotificationController);
99 };
100 
101 }  // namespace ash
102 
103 #endif  // ASH_DISPLAY_RESOLUTION_NOTIFICATION_CONTROLLER_H_
104