page_live_state_decorator.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright 2019 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. #include "components/performance_manager/public/decorators/page_live_state_decorator.h"
  5. #include "base/memory/raw_ptr.h"
  6. #include "base/observer_list.h"
  7. #include "base/sequence_checker.h"
  8. #include "components/performance_manager/decorators/decorators_utils.h"
  9. #include "components/performance_manager/graph/node_attached_data_impl.h"
  10. #include "components/performance_manager/graph/page_node_impl.h"
  11. #include "components/performance_manager/public/graph/node_data_describer_registry.h"
  12. #include "components/performance_manager/public/performance_manager.h"
  13. #include "content/public/browser/browser_thread.h"
  14. namespace performance_manager {
  15. namespace {
  16. // Private implementation of the node attached data. This keeps the complexity
  17. // out of the header file.
  18. class PageLiveStateDataImpl
  19. : public PageLiveStateDecorator::Data,
  20. public NodeAttachedDataImpl<PageLiveStateDataImpl> {
  21. public:
  22. struct Traits : public NodeAttachedDataInMap<PageNodeImpl> {};
  23. ~PageLiveStateDataImpl() override = default;
  24. PageLiveStateDataImpl(const PageLiveStateDataImpl& other) = delete;
  25. PageLiveStateDataImpl& operator=(const PageLiveStateDataImpl&) = delete;
  26. // PageLiveStateDecorator::Data:
  27. bool IsConnectedToUSBDevice() const override {
  28. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  29. return is_connected_to_usb_device_;
  30. }
  31. bool IsConnectedToBluetoothDevice() const override {
  32. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  33. return is_connected_to_bluetooth_device_;
  34. }
  35. bool IsCapturingVideo() const override {
  36. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  37. return is_capturing_video_;
  38. }
  39. bool IsCapturingAudio() const override {
  40. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  41. return is_capturing_audio_;
  42. }
  43. bool IsBeingMirrored() const override {
  44. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  45. return is_being_mirrored_;
  46. }
  47. bool IsCapturingWindow() const override {
  48. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  49. return is_capturing_window_;
  50. }
  51. bool IsCapturingDisplay() const override {
  52. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  53. return is_capturing_display_;
  54. }
  55. bool IsAutoDiscardable() const override {
  56. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  57. return is_auto_discardable_;
  58. }
  59. bool WasDiscarded() const override {
  60. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  61. return was_discarded_;
  62. }
  63. void SetIsConnectedToUSBDeviceForTesting(bool value) override {
  64. set_is_connected_to_usb_device(value);
  65. }
  66. void SetIsConnectedToBluetoothDeviceForTesting(bool value) override {
  67. set_is_connected_to_bluetooth_device(value);
  68. }
  69. void SetIsCapturingVideoForTesting(bool value) override {
  70. set_is_capturing_video(value);
  71. }
  72. void SetIsCapturingAudioForTesting(bool value) override {
  73. set_is_capturing_audio(value);
  74. }
  75. void SetIsBeingMirroredForTesting(bool value) override {
  76. set_is_being_mirrored(value);
  77. }
  78. void SetIsCapturingWindowForTesting(bool value) override {
  79. set_is_capturing_window(value);
  80. }
  81. void SetIsCapturingDisplayForTesting(bool value) override {
  82. set_is_capturing_display(value);
  83. }
  84. void SetIsAutoDiscardableForTesting(bool value) override {
  85. set_is_auto_discardable(value);
  86. }
  87. void SetWasDiscardedForTesting(bool value) override {
  88. set_was_discarded(value);
  89. }
  90. void set_is_connected_to_usb_device(bool is_connected_to_usb_device) {
  91. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  92. if (is_connected_to_usb_device_ == is_connected_to_usb_device)
  93. return;
  94. is_connected_to_usb_device_ = is_connected_to_usb_device;
  95. for (auto& obs : observers_)
  96. obs.OnIsConnectedToUSBDeviceChanged(page_node_);
  97. }
  98. void set_is_connected_to_bluetooth_device(
  99. bool is_connected_to_bluetooth_device) {
  100. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  101. if (is_connected_to_bluetooth_device_ == is_connected_to_bluetooth_device)
  102. return;
  103. is_connected_to_bluetooth_device_ = is_connected_to_bluetooth_device;
  104. for (auto& obs : observers_)
  105. obs.OnIsConnectedToBluetoothDeviceChanged(page_node_);
  106. }
  107. void set_is_capturing_video(bool is_capturing_video) {
  108. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  109. if (is_capturing_video_ == is_capturing_video)
  110. return;
  111. is_capturing_video_ = is_capturing_video;
  112. for (auto& obs : observers_)
  113. obs.OnIsCapturingVideoChanged(page_node_);
  114. }
  115. void set_is_capturing_audio(bool is_capturing_audio) {
  116. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  117. if (is_capturing_audio_ == is_capturing_audio)
  118. return;
  119. is_capturing_audio_ = is_capturing_audio;
  120. for (auto& obs : observers_)
  121. obs.OnIsCapturingAudioChanged(page_node_);
  122. }
  123. void set_is_being_mirrored(bool is_being_mirrored) {
  124. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  125. if (is_being_mirrored_ == is_being_mirrored)
  126. return;
  127. is_being_mirrored_ = is_being_mirrored;
  128. for (auto& obs : observers_)
  129. obs.OnIsBeingMirroredChanged(page_node_);
  130. }
  131. void set_is_capturing_window(bool is_capturing_window) {
  132. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  133. if (is_capturing_window_ == is_capturing_window)
  134. return;
  135. is_capturing_window_ = is_capturing_window;
  136. for (auto& obs : observers_)
  137. obs.OnIsCapturingWindowChanged(page_node_);
  138. }
  139. void set_is_capturing_display(bool is_capturing_display) {
  140. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  141. if (is_capturing_display_ == is_capturing_display)
  142. return;
  143. is_capturing_display_ = is_capturing_display;
  144. for (auto& obs : observers_)
  145. obs.OnIsCapturingDisplayChanged(page_node_);
  146. }
  147. void set_is_auto_discardable(bool is_auto_discardable) {
  148. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  149. if (is_auto_discardable_ == is_auto_discardable)
  150. return;
  151. is_auto_discardable_ = is_auto_discardable;
  152. for (auto& obs : observers_)
  153. obs.OnIsAutoDiscardableChanged(page_node_);
  154. }
  155. void set_was_discarded(bool was_discarded) {
  156. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  157. if (was_discarded_ == was_discarded)
  158. return;
  159. was_discarded_ = was_discarded;
  160. for (auto& obs : observers_)
  161. obs.OnWasDiscardedChanged(page_node_);
  162. }
  163. private:
  164. // Make the impl our friend so it can access the constructor and any
  165. // storage providers.
  166. friend class ::performance_manager::NodeAttachedDataImpl<
  167. PageLiveStateDataImpl>;
  168. explicit PageLiveStateDataImpl(const PageNodeImpl* page_node)
  169. : page_node_(page_node) {}
  170. bool is_connected_to_usb_device_ GUARDED_BY_CONTEXT(sequence_checker_) =
  171. false;
  172. bool is_connected_to_bluetooth_device_ GUARDED_BY_CONTEXT(sequence_checker_) =
  173. false;
  174. bool is_capturing_video_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  175. bool is_capturing_audio_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  176. bool is_being_mirrored_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  177. bool is_capturing_window_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  178. bool is_capturing_display_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  179. bool is_auto_discardable_ GUARDED_BY_CONTEXT(sequence_checker_) = true;
  180. bool was_discarded_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  181. const raw_ptr<const PageNode> page_node_;
  182. };
  183. const char kDescriberName[] = "PageLiveStateDecorator";
  184. } // namespace
  185. // static
  186. void PageLiveStateDecorator::OnIsConnectedToUSBDeviceChanged(
  187. content::WebContents* contents,
  188. bool is_connected_to_usb_device) {
  189. SetPropertyForWebContentsPageNode(
  190. contents, &PageLiveStateDataImpl::set_is_connected_to_usb_device,
  191. is_connected_to_usb_device);
  192. }
  193. // static
  194. void PageLiveStateDecorator::OnIsConnectedToBluetoothDeviceChanged(
  195. content::WebContents* contents,
  196. bool is_connected_to_bluetooth_device) {
  197. SetPropertyForWebContentsPageNode(
  198. contents, &PageLiveStateDataImpl::set_is_connected_to_bluetooth_device,
  199. is_connected_to_bluetooth_device);
  200. }
  201. // static
  202. void PageLiveStateDecorator::OnIsCapturingVideoChanged(
  203. content::WebContents* contents,
  204. bool is_capturing_video) {
  205. SetPropertyForWebContentsPageNode(
  206. contents, &PageLiveStateDataImpl::set_is_capturing_video,
  207. is_capturing_video);
  208. }
  209. // static
  210. void PageLiveStateDecorator::OnIsCapturingAudioChanged(
  211. content::WebContents* contents,
  212. bool is_capturing_audio) {
  213. SetPropertyForWebContentsPageNode(
  214. contents, &PageLiveStateDataImpl::set_is_capturing_audio,
  215. is_capturing_audio);
  216. }
  217. // static
  218. void PageLiveStateDecorator::OnIsBeingMirroredChanged(
  219. content::WebContents* contents,
  220. bool is_being_mirrored) {
  221. SetPropertyForWebContentsPageNode(
  222. contents, &PageLiveStateDataImpl::set_is_being_mirrored,
  223. is_being_mirrored);
  224. }
  225. // static
  226. void PageLiveStateDecorator::OnIsCapturingWindowChanged(
  227. content::WebContents* contents,
  228. bool is_capturing_window) {
  229. SetPropertyForWebContentsPageNode(
  230. contents, &PageLiveStateDataImpl::set_is_capturing_window,
  231. is_capturing_window);
  232. }
  233. // static
  234. void PageLiveStateDecorator::OnIsCapturingDisplayChanged(
  235. content::WebContents* contents,
  236. bool is_capturing_display) {
  237. SetPropertyForWebContentsPageNode(
  238. contents, &PageLiveStateDataImpl::set_is_capturing_display,
  239. is_capturing_display);
  240. }
  241. // static
  242. void PageLiveStateDecorator::SetIsAutoDiscardable(
  243. content::WebContents* contents,
  244. bool is_auto_discardable) {
  245. SetPropertyForWebContentsPageNode(
  246. contents, &PageLiveStateDataImpl::set_is_auto_discardable,
  247. is_auto_discardable);
  248. }
  249. // static
  250. void PageLiveStateDecorator::SetWasDiscarded(content::WebContents* contents,
  251. bool was_discarded) {
  252. SetPropertyForWebContentsPageNode(
  253. contents, &PageLiveStateDataImpl::set_was_discarded, was_discarded);
  254. }
  255. void PageLiveStateDecorator::OnPassedToGraph(Graph* graph) {
  256. graph->GetNodeDataDescriberRegistry()->RegisterDescriber(this,
  257. kDescriberName);
  258. }
  259. void PageLiveStateDecorator::OnTakenFromGraph(Graph* graph) {
  260. graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this);
  261. }
  262. base::Value PageLiveStateDecorator::DescribePageNodeData(
  263. const PageNode* node) const {
  264. auto* data = Data::FromPageNode(node);
  265. if (!data)
  266. return base::Value();
  267. base::Value ret(base::Value::Type::DICTIONARY);
  268. ret.SetBoolKey("IsConnectedToUSBDevice", data->IsConnectedToUSBDevice());
  269. ret.SetBoolKey("IsConnectedToBluetoothDevice",
  270. data->IsConnectedToBluetoothDevice());
  271. ret.SetBoolKey("IsCapturingVideo", data->IsCapturingVideo());
  272. ret.SetBoolKey("IsCapturingAudio", data->IsCapturingAudio());
  273. ret.SetBoolKey("IsBeingMirrored", data->IsBeingMirrored());
  274. ret.SetBoolKey("IsCapturingWindow", data->IsCapturingWindow());
  275. ret.SetBoolKey("IsCapturingDisplay", data->IsCapturingDisplay());
  276. ret.SetBoolKey("IsAutoDiscardable", data->IsAutoDiscardable());
  277. ret.SetBoolKey("WasDiscarded", data->WasDiscarded());
  278. return ret;
  279. }
  280. PageLiveStateDecorator::Data::Data() = default;
  281. PageLiveStateDecorator::Data::~Data() = default;
  282. void PageLiveStateDecorator::Data::AddObserver(
  283. PageLiveStateObserver* observer) {
  284. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  285. observers_.AddObserver(observer);
  286. }
  287. void PageLiveStateDecorator::Data::RemoveObserver(
  288. PageLiveStateObserver* observer) {
  289. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  290. observers_.RemoveObserver(observer);
  291. }
  292. const PageLiveStateDecorator::Data* PageLiveStateDecorator::Data::FromPageNode(
  293. const PageNode* page_node) {
  294. return PageLiveStateDataImpl::Get(PageNodeImpl::FromNode(page_node));
  295. }
  296. PageLiveStateDecorator::Data*
  297. PageLiveStateDecorator::Data::GetOrCreateForPageNode(
  298. const PageNode* page_node) {
  299. return PageLiveStateDataImpl::GetOrCreate(PageNodeImpl::FromNode(page_node));
  300. }
  301. PageLiveStateObserver::PageLiveStateObserver() = default;
  302. PageLiveStateObserver::~PageLiveStateObserver() = default;
  303. } // namespace performance_manager