Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: services/resource_coordinator/coordination_unit/tab_cpu_usage_observer.cc

Issue 2925123002: NOCOMMIT PROTOTYPE [GRC] Tab CPU Usage Observer (Closed)
Patch Set: Rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 #include "services/resource_coordinator/coordination_unit/tab_cpu_usage_observer .h"
6
7 #include <stdint.h>
8
9 #include <ostream>
10 #include <utility>
11
12 #include "base/values.h"
13 #include "services/resource_coordinator/coordination_unit/coordination_unit_impl .h"
14 #include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
15 #include "services/resource_coordinator/public/interfaces/coordination_unit.mojo m.h"
16
17 namespace resource_coordinator {
18
19 const unsigned int TabObserver::kMaxCPUUsageMeasurementTicks = 3;
20
21 TabObserver::TabObserver() : cpu_measurement_ticks_(0u) {}
22
23 TabObserver::~TabObserver() = default;
24
25 void TabObserver::AttributeCPUUsage(double cpu_usage) {
26 ++cpu_measurement_ticks_;
27 }
28
29 bool TabObserver::IsObserving() {
30 return !url_.empty() && cpu_measurement_ticks_ < kMaxCPUUsageMeasurementTicks;
31 }
32
33 void TabObserver::TabURLChanged(
34 const CoordinationUnitImpl* tab_coordination_unit,
35 mojom::PropertyType tab_url_property) {
36 DCHECK(tab_coordination_unit->id().type ==
37 CoordinationUnitType::kWebContents);
38 DCHECK(tab_url_property == mojom::PropertyType::kTabURL);
39
40 base::Value tab_url_value =
41 tab_coordination_unit->GetProperty(tab_url_property);
42 DCHECK(tab_url_value.is_string());
43 url_ = tab_url_value.GetString();
44
45 // Reset ticks
46 cpu_measurement_ticks_ = 0u;
47 }
48
49 ProcessObserver::ProcessObserver() = default;
50
51 ProcessObserver::~ProcessObserver() = default;
52
53 void ProcessObserver::RecalculateAttributableTabs(
54 const CoordinationUnitImpl* process_coordination_unit,
55 const CoordinationUnitImpl* frame_coordination_unit) {
56 DCHECK(process_coordination_unit->id().type ==
57 CoordinationUnitType::kProcess);
58 DCHECK(frame_coordination_unit->id().type == CoordinationUnitType::kFrame);
59
60 attributable_tabs_.clear();
61
62 DCHECK(tab_cpu_usage_observer_);
63 std::unordered_map<CoordinationUnitID, TabObserver>&
64 registered_tab_observers = tab_cpu_usage_observer_->tab_observers();
65 // Any WebContents CoordinationUnit that is a parent of any of the
66 // Process's child Frame CoordinationUnit is considered to attributable
67 // for the Process's CPU usage.
68 for (auto* child : process_coordination_unit->children()) {
69 if (child->id().type == CoordinationUnitType::kFrame) {
70 for (auto* frame_parent : child->parents()) {
71 if (frame_parent->id().type == CoordinationUnitType::kWebContents) {
72 // Another frame within a tab may have previously inserted its, so
73 // its acceptable to not check if the insertion was successful.
74 auto tab_observer_it =
75 registered_tab_observers.find(frame_parent->id());
76 DCHECK(tab_observer_it != registered_tab_observers.end());
77 attributable_tabs_.insert(
78 std::make_pair(frame_parent->id(), &tab_observer_it->second));
79 }
80 }
81 }
82 }
83 }
84
85 void ProcessObserver::NewCPUUsageMeasurement(
86 const CoordinationUnitImpl* process_coordination_unit,
87 mojom::PropertyType process_cpu_usage_property) {
88 DCHECK(process_coordination_unit->id().type ==
89 CoordinationUnitType::kProcess);
90 DCHECK(process_cpu_usage_property == mojom::PropertyType::kProcessCPUUsage);
91
92 if (attributable_tabs_.empty()) {
93 return;
94 }
95
96 base::Value process_cpu_usage_value =
97 process_coordination_unit->GetProperty(process_cpu_usage_property);
98 DCHECK(process_cpu_usage_value.is_double());
99
100 // CPU attribution for multiple tabs within a process is currently naive in
101 // that the measured process CPU utilization is attributed equally amongst the
102 // tabs.
103 double tab_cpu_usage = process_cpu_usage_value.GetDouble() /
104 static_cast<double>(attributable_tabs_.size());
105
106 for (auto& tab_observer : attributable_tabs_) {
107 if (tab_observer.second->IsObserving()) {
108 tab_observer.second->AttributeCPUUsage(tab_cpu_usage);
109 }
110 }
111 }
112
113 TabCPUUsageObserver::TabCPUUsageObserver() = default;
114
115 TabCPUUsageObserver::~TabCPUUsageObserver() = default;
116
117 void TabCPUUsageObserver::TabCoordinationUnitCreated(
118 CoordinationUnitImpl* tab_coordination_unit) {
119 DCHECK(!tab_observers_.count(tab_coordination_unit->id()));
120
121 auto& tab_observer = tab_observers_[tab_coordination_unit->id()];
122 tab_observer.SetTabCPUUsageObserver(this);
123
124 tab_coordination_unit->on_property_changed_event_listeners().AddListener(
125 base::Bind(&TabObserver::TabURLChanged, base::Unretained(&tab_observer)),
126 mojom::PropertyType::kTabURL);
127
128 tab_coordination_unit->on_will_be_destroyed_event_listeners().AddListener(
129 base::Bind(&TabCPUUsageObserver::RemoveTabObserver,
130 base::Unretained(this)));
131 }
132
133 void TabCPUUsageObserver::ProcessCoordinationUnitCreated(
134 CoordinationUnitImpl* process_coordination_unit) {
135 DCHECK(!process_observers_.count(process_coordination_unit->id()));
136 ProcessObserver& process_observer =
137 process_observers_[process_coordination_unit->id()];
138 process_observer.SetTabCPUUsageObserver(this);
139
140 process_coordination_unit->on_add_child_event_listeners().AddListener(
141 base::Bind(&ProcessObserver::RecalculateAttributableTabs,
142 base::Unretained(&process_observer)),
143 CoordinationUnitType::kFrame);
144
145 process_coordination_unit->on_remove_child_event_listeners().AddListener(
146 base::Bind(&ProcessObserver::RecalculateAttributableTabs,
147 base::Unretained(&process_observer)),
148 CoordinationUnitType::kFrame);
149
150 process_coordination_unit->on_property_changed_event_listeners().AddListener(
151 base::Bind(&ProcessObserver::NewCPUUsageMeasurement,
152 base::Unretained(&process_observer)),
153 mojom::PropertyType::kProcessCPUUsage);
Zhen Wang 2017/06/16 22:47:45 I see your point here that one may want to listen
154
155 process_coordination_unit->on_will_be_destroyed_event_listeners().AddListener(
156 base::Bind(&TabCPUUsageObserver::RemoveProcessObserver,
157 base::Unretained(this)));
158 }
159
160 void TabCPUUsageObserver::CoordinationUnitCreated(
161 CoordinationUnitImpl* coordination_unit) {
162 switch (coordination_unit->id().type) {
163 case CoordinationUnitType::kWebContents:
164 TabCoordinationUnitCreated(coordination_unit);
165 break;
166 case CoordinationUnitType::kProcess:
167 ProcessCoordinationUnitCreated(coordination_unit);
168 break;
169 case CoordinationUnitType::kFrame:
170 break;
171 default:
172 break;
173 }
174
175 if (coordination_unit->id().type != CoordinationUnitType::kProcess) {
176 return;
177 }
178 }
179
180 void TabCPUUsageObserver::RemoveProcessObserver(
181 const CoordinationUnitImpl* process_coordination_unit) {
182 DCHECK(process_observers_.count(process_coordination_unit->id()));
183 process_observers_.erase(process_coordination_unit->id());
184 }
185
186 void TabCPUUsageObserver::RemoveTabObserver(
187 const CoordinationUnitImpl* tab_coordination_unit) {
188 DCHECK(tab_observers_.count(tab_coordination_unit->id()));
189 tab_observers_.erase(tab_coordination_unit->id());
190 }
191
192 } // namespace resource_coordinator
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698