tab_helper_frame_node_source.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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/tab_helper_frame_node_source.h"
  5. #include <utility>
  6. #include "content/public/browser/render_frame_host.h"
  7. #include "content/public/browser/web_contents.h"
  8. namespace performance_manager {
  9. TabHelperFrameNodeSource::TabHelperFrameNodeSource()
  10. : performance_manager_tab_helper_observations_(this) {}
  11. TabHelperFrameNodeSource::~TabHelperFrameNodeSource() {
  12. DCHECK(observed_frame_nodes_.empty());
  13. DCHECK(!performance_manager_tab_helper_observations_.IsObservingAnySource());
  14. }
  15. FrameNodeImpl* TabHelperFrameNodeSource::GetFrameNode(
  16. content::GlobalRenderFrameHostId render_process_host_id) {
  17. // Retrieve the client's RenderFrameHost and its associated
  18. // PerformanceManagerTabHelper.
  19. auto* render_frame_host =
  20. content::RenderFrameHost::FromID(render_process_host_id);
  21. if (!render_frame_host)
  22. return nullptr;
  23. PerformanceManagerTabHelper* performance_manager_tab_helper =
  24. PerformanceManagerTabHelper::FromWebContents(
  25. content::WebContents::FromRenderFrameHost(render_frame_host));
  26. if (!performance_manager_tab_helper)
  27. return nullptr;
  28. return performance_manager_tab_helper->GetFrameNode(render_frame_host);
  29. }
  30. void TabHelperFrameNodeSource::SubscribeToFrameNode(
  31. content::GlobalRenderFrameHostId render_process_host_id,
  32. OnbeforeFrameNodeRemovedCallback on_before_frame_node_removed_callback) {
  33. auto* render_frame_host =
  34. content::RenderFrameHost::FromID(render_process_host_id);
  35. DCHECK(render_frame_host);
  36. PerformanceManagerTabHelper* performance_manager_tab_helper =
  37. PerformanceManagerTabHelper::FromWebContents(
  38. content::WebContents::FromRenderFrameHost(render_frame_host));
  39. DCHECK(performance_manager_tab_helper);
  40. FrameNodeImpl* frame_node =
  41. performance_manager_tab_helper->GetFrameNode(render_frame_host);
  42. // Add the frame to the set of observed frames that belongs to
  43. // |performance_manager_tab_helper|.
  44. if (AddObservedFrameNode(performance_manager_tab_helper, frame_node)) {
  45. // Start observing the tab helper only if this is the first observed frame
  46. // that is associated with it.
  47. performance_manager_tab_helper_observations_.AddObservation(
  48. performance_manager_tab_helper);
  49. }
  50. // Then remember the frame's callback.
  51. bool inserted =
  52. frame_node_callbacks_
  53. .insert(std::make_pair(
  54. frame_node, std::move(on_before_frame_node_removed_callback)))
  55. .second;
  56. DCHECK(inserted);
  57. }
  58. void TabHelperFrameNodeSource::UnsubscribeFromFrameNode(
  59. content::GlobalRenderFrameHostId render_process_host_id) {
  60. auto* render_frame_host =
  61. content::RenderFrameHost::FromID(render_process_host_id);
  62. DCHECK(render_frame_host);
  63. PerformanceManagerTabHelper* performance_manager_tab_helper =
  64. PerformanceManagerTabHelper::FromWebContents(
  65. content::WebContents::FromRenderFrameHost(render_frame_host));
  66. DCHECK(performance_manager_tab_helper);
  67. FrameNodeImpl* frame_node =
  68. performance_manager_tab_helper->GetFrameNode(render_frame_host);
  69. // Remove the frame's callback without invoking it.
  70. size_t removed = frame_node_callbacks_.erase(frame_node);
  71. DCHECK_EQ(removed, 1u);
  72. // And also remove the frame from the set of observed frames that belongs to
  73. // |performance_manager_tab_helper|.
  74. if (RemoveObservedFrameNode(performance_manager_tab_helper, frame_node)) {
  75. // Stop observing that tab helper if there no longer are any observed
  76. // frames that are associated with it.
  77. performance_manager_tab_helper_observations_.RemoveObservation(
  78. performance_manager_tab_helper);
  79. }
  80. }
  81. void TabHelperFrameNodeSource::OnBeforeFrameNodeRemoved(
  82. PerformanceManagerTabHelper* performance_manager_tab_helper,
  83. FrameNodeImpl* frame_node) {
  84. // The tab helper owns many other frames than the ones this instance cares
  85. // about. Ignore irrelevant notifications.
  86. auto it = frame_node_callbacks_.find(frame_node);
  87. if (it == frame_node_callbacks_.end())
  88. return;
  89. // Invoke the frame's callback and remove it.
  90. std::move(it->second).Run(frame_node);
  91. frame_node_callbacks_.erase(it);
  92. // And also remove the frame from the set of observed frames that belong to
  93. // |performance_manager_tab_helper|.
  94. if (RemoveObservedFrameNode(performance_manager_tab_helper, frame_node)) {
  95. // Stop observing that tab helper if there no longer are any observed
  96. // frames that are associated with it.
  97. performance_manager_tab_helper_observations_.RemoveObservation(
  98. performance_manager_tab_helper);
  99. }
  100. }
  101. bool TabHelperFrameNodeSource::AddObservedFrameNode(
  102. PerformanceManagerTabHelper* performance_manager_tab_helper,
  103. FrameNodeImpl* frame_node) {
  104. auto insertion_result =
  105. observed_frame_nodes_.insert({performance_manager_tab_helper, {}});
  106. base::flat_set<FrameNodeImpl*>& frame_nodes = insertion_result.first->second;
  107. bool inserted = frame_nodes.insert(frame_node).second;
  108. DCHECK(inserted);
  109. return insertion_result.second;
  110. }
  111. bool TabHelperFrameNodeSource::RemoveObservedFrameNode(
  112. PerformanceManagerTabHelper* performance_manager_tab_helper,
  113. FrameNodeImpl* frame_node) {
  114. auto it = observed_frame_nodes_.find(performance_manager_tab_helper);
  115. DCHECK(it != observed_frame_nodes_.end());
  116. base::flat_set<FrameNodeImpl*>& frame_nodes = it->second;
  117. size_t removed = frame_nodes.erase(frame_node);
  118. DCHECK_EQ(removed, 1u);
  119. if (frame_nodes.empty()) {
  120. observed_frame_nodes_.erase(it);
  121. return true;
  122. }
  123. return false;
  124. }
  125. } // namespace performance_manager