1 /*
2  *  Copyright (C) 2017-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include <memory>
12 #include <utility>
13 
14 namespace KODI
15 {
16 namespace WINDOWING
17 {
18 
19 class COSScreenSaverManager;
20 
21 /**
22  * Inhibit the OS screen saver as long as this object is alive
23  *
24  * Destroy or call \ref Release to stop this inhibitor from being active.
25  * The OS screen saver may still be inhibited as long as other inhibitors are
26  * active though.
27  *
28  * \note Make sure to release or destroy the inhibitor before the \ref
29  *       COSScreenSaverManager is destroyed
30  */
31 class COSScreenSaverInhibitor
32 {
33 public:
34   COSScreenSaverInhibitor() noexcept;
35   COSScreenSaverInhibitor(COSScreenSaverInhibitor&& other) noexcept;
36   COSScreenSaverInhibitor& operator=(COSScreenSaverInhibitor&& other) noexcept;
37   ~COSScreenSaverInhibitor() noexcept;
38   void Release();
39   bool IsActive() const;
40   operator bool() const;
41 
42 private:
43   friend class COSScreenSaverManager;
44   explicit COSScreenSaverInhibitor(COSScreenSaverManager* manager);
45   bool m_active;
46   COSScreenSaverManager* m_manager;
47 
48   COSScreenSaverInhibitor(COSScreenSaverInhibitor const& other) = delete;
49   COSScreenSaverInhibitor& operator=(COSScreenSaverInhibitor const& other) = delete;
50 };
51 
52 /**
53  * Interface for OS screen saver control implementations
54  */
55 class IOSScreenSaver
56 {
57 public:
58   virtual ~IOSScreenSaver() = default;
59   /**
60    * Do not allow the OS screen saver to become active
61    *
62    * Calling this function multiple times without calling \ref Unhibit
63    * MUST NOT produce any side-effects.
64    */
65   virtual void Inhibit() = 0;
66   /**
67    * Allow the OS screen saver to become active again
68    *
69    * Calling this function multiple times or at all without calling \ref Inhibit
70    * MUST NOT produce any side-effects.
71    */
72   virtual void Uninhibit() = 0;
73 };
74 
75 /**
76  * Dummy implementation of IOSScreenSaver
77  */
78 class CDummyOSScreenSaver : public IOSScreenSaver
79 {
80 public:
Inhibit()81   void Inhibit() override {}
Uninhibit()82   void Uninhibit() override {}
83 };
84 
85 /**
86  * Manage the OS screen saver
87  *
88  * This class keeps track of a number of \ref COSScreenSaverInhibitor instances
89  * and keeps the OS screen saver inhibited as long as at least one of them
90  * exists and is active.
91  */
92 class COSScreenSaverManager
93 {
94 public:
95   /**
96    * Create manager with backing OS-specific implementation
97    */
98   explicit COSScreenSaverManager(std::unique_ptr<IOSScreenSaver> impl);
99   /**
100    * Create inhibitor that prevents the OS screen saver from becoming active as
101    * long as it is alive
102    */
103   COSScreenSaverInhibitor CreateInhibitor();
104   /**
105    * Check whether the OS screen saver is currently inhibited
106    */
107   bool IsInhibited();
108 
109 private:
110   friend class COSScreenSaverInhibitor;
111   void RemoveInhibitor();
112 
113   unsigned int m_inhibitionCount{0u};
114   std::unique_ptr<IOSScreenSaver> m_impl;
115 };
116 
117 }
118 }
119