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

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

Issue 2710823003: NOCOMMIT prototype: GRC service plumbing and process priority
Patch Set: Buildfixes Created 3 years, 9 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.h"
6
7 #include "base/hash.h"
8 #include "base/lazy_instance.h"
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "mojo/public/cpp/bindings/strong_binding.h"
12 #include "services/service_manager/public/cpp/connection.h"
13
14 namespace resource_coordinator {
15
16 namespace {
17
18 base::LazyInstance<std::unordered_map<int64_t, CoordinationUnit*>>::Leaky
19 g_cu_map = LAZY_INSTANCE_INITIALIZER;
20
21 int64_t CUIDHash(mojom::CoordinationUnitIDPtr id) {
22 // TODO: hash the type into the upper 32 bits.
23 return base::Hash(id->id);
24 }
25
26 } // namespace
27
28 CoordinationUnit::CoordinationUnit(mojom::CoordinationUnitIDPtr options) {
29 // LOG(ERROR) << "CoordinationUnit::CoordinationUnit(0x" << this << ")";
30 // LOG(ERROR) << "id(" << options->type << ":" << options->id << ")";
31
32 type_ = options->type;
33 id_ = options->id;
34 id_hash_ = CUIDHash(std::move(options));
35 g_cu_map.Get().insert(std::make_pair(id_hash_, this));
36 }
37
38 CoordinationUnit::~CoordinationUnit() {
39 // LOG(ERROR) << "CoordinationUnit::~CoordinationUnit(0x" << this << ")";
40 g_cu_map.Get().erase(id_hash_);
41
42 for (auto* child : children_) {
43 child->RemoveParent(this);
44 }
45
46 for (auto* parent : parents_) {
47 parent->RemoveChild(this);
48 }
49 }
50
51 bool CoordinationUnit::SelfOrParentHasFlagSet(StateFlags state) {
52 const base::Optional<bool>& state_flag = state_flags_[state];
53 if (state_flag && *state_flag)
54 return true;
55
56 for (auto* parent : parents_) {
57 if (parent->SelfOrParentHasFlagSet(state))
58 return true;
59 }
60
61 return false;
62 }
63
64 void CoordinationUnit::RecalcPolicy() {
65 if (!policy_callback_)
66 return;
67
68 bool background_priority = !SelfOrParentHasFlagSet(TAB_VISIBLE) &&
69 !SelfOrParentHasFlagSet(AUDIO_PLAYING);
70
71 // LOG(ERROR) << "Should background: " << background_priority;
72
73 for (auto* child : children_) {
74 child->RecalcPolicy();
75 }
76
77 // Send the priority to the client if it's new or changed.
78 if (!current_policy_)
79 current_policy_ = mojom::Policy::New();
80 else if (current_policy_->use_background_priority == background_priority)
81 return;
82
83 mojom::PolicyPtr policy = mojom::Policy::New();
84 policy->use_background_priority = background_priority;
85 current_policy_->use_background_priority = background_priority;
86
87 policy_callback_->SetPolicy(std::move(policy));
88 }
89
90 void CoordinationUnit::SendEvent(mojom::EventPtr event) {
91 // LOG(ERROR) << "CoordinationUnit::SendEvent(0x" << this << "): " <<
92 // event->type;
93
94 switch (event->type) {
95 case mojom::EventType::ON_WEBCONTENTS_SHOWN:
96 state_flags_[TAB_VISIBLE] = true;
97 break;
98 case mojom::EventType::ON_WEBCONTENTS_HIDDEN:
99 state_flags_[TAB_VISIBLE] = false;
100 break;
101 case mojom::EventType::ON_PROCESS_AUDIO_STARTED:
102 state_flags_[AUDIO_PLAYING] = true;
103 break;
104 case mojom::EventType::ON_PROCESS_AUDIO_STOPPED:
105 state_flags_[AUDIO_PLAYING] = false;
106 break;
107 default:
108 return;
109 }
110
111 RecalcPolicy();
112 }
113
114 void CoordinationUnit::GetID(const GetIDCallback& callback) {
115 mojom::CoordinationUnitIDPtr id = mojom::CoordinationUnitID::New();
116 id->type = type_;
117 id->id = id_;
118 callback.Run(std::move(id));
119 }
120
121 void CoordinationUnit::Duplicate(mojom::CoordinationUnitRequest request) {
122 // LOG(ERROR) << "CoordinationUnit::Duplicate(0x" << this << ")";
123 bindings_.AddBinding(this, std::move(request));
124 }
125
126 void CoordinationUnit::AddChild(mojom::CoordinationUnitIDPtr child_id) {
127 // LOG(ERROR) << "CoordinationUnit::AddChild(" << type_ << ":" << id_ << " ->
128 // "
129 // << child_id->type << ":" << child_id->id << ")";
130
131 auto child_iter = g_cu_map.Get().find(CUIDHash(std::move(child_id)));
132 if (child_iter != g_cu_map.Get().end()) {
133 CoordinationUnit* child = child_iter->second;
134 // TODO: Ensure we're staying a DAG and not adding any cycles here.
135 if (AddChild(child)) {
136 child->AddParent(this);
137 }
138 }
139 }
140
141 bool CoordinationUnit::AddChild(CoordinationUnit* child) {
142 if (children_.find(child) != children_.end())
143 return false;
144
145 children_.insert(child);
146
147 return true;
148 }
149
150 void CoordinationUnit::RemoveChild(CoordinationUnit* child) {
151 size_t children_removed = children_.erase(child);
152 CHECK_EQ(1u, children_removed);
153 }
154
155 void CoordinationUnit::AddParent(CoordinationUnit* parent) {
156 DCHECK(parents_.find(parent) == parents_.end());
157 parents_.insert(parent);
158
159 RecalcPolicy();
160 }
161
162 void CoordinationUnit::RemoveParent(CoordinationUnit* parent) {
163 size_t parents_removed = parents_.erase(parent);
164 CHECK_EQ(1u, parents_removed);
165
166 RecalcPolicy();
167 }
168
169 void CoordinationUnit::SetPolicyCallback(mojom::PolicyCallbackPtr callback) {
170 callback.set_connection_error_handler(base::Bind(
171 &CoordinationUnit::UnregisterPolicyCallback, base::Unretained(this)));
172
173 policy_callback_ = std::move(callback);
174
175 RecalcPolicy();
176 }
177
178 void CoordinationUnit::UnregisterPolicyCallback() {
179 policy_callback_.reset();
180 current_policy_.reset();
181 }
182
183 } // namespace resource_coordinator
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698