| Index: services/resource_coordinator/coordination_unit/coordination_unit_impl.cc | 
| diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc | 
| index b50d98fcc700eaf820347721d7b6c812bfaf453b..cff76af3005d3f5c7e863ca0728ab96e636580d6 100644 | 
| --- a/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc | 
| +++ b/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc | 
| @@ -157,7 +157,17 @@ bool CoordinationUnitImpl::AddChild(CoordinationUnitImpl* child) { | 
| // We don't recalculate the policy here as policies are only dependent | 
| // on the current CU or its parents, not its children. In other words, | 
| // policies only bubble down. | 
| -  return children_.count(child) ? false : children_.insert(child).second; | 
| +  bool success = | 
| +      children_.count(child) ? false : children_.insert(child).second; | 
| + | 
| +  if (success) { | 
| +    for (auto listener : | 
| +         on_add_child_event_listeners_.GetListeners(child->id().type)) { | 
| +      listener.Run(this, child); | 
| +    } | 
| +  } | 
| + | 
| +  return success; | 
| } | 
|  | 
| void CoordinationUnitImpl::RemoveChild(const CoordinationUnitID& child_id) { | 
| @@ -181,13 +191,27 @@ void CoordinationUnitImpl::RemoveChild(const CoordinationUnitID& child_id) { | 
|  | 
| bool CoordinationUnitImpl::RemoveChild(CoordinationUnitImpl* child) { | 
| size_t children_removed = children_.erase(child); | 
| -  return children_removed > 0; | 
| +  bool success = children_removed > 0; | 
| + | 
| +  if (success) { | 
| +    for (auto listener : | 
| +         on_remove_child_event_listeners_.GetListeners(child->id().type)) { | 
| +      listener.Run(this, child); | 
| +    } | 
| +  } | 
| + | 
| +  return success; | 
| } | 
|  | 
| void CoordinationUnitImpl::AddParent(CoordinationUnitImpl* parent) { | 
| DCHECK_EQ(0u, parents_.count(parent)); | 
| parents_.insert(parent); | 
|  | 
| +  for (auto listener : | 
| +       on_add_parent_event_listeners_.GetListeners(parent->id().type)) { | 
| +    listener.Run(this, parent); | 
| +  } | 
| + | 
| RecalcCoordinationPolicy(); | 
| } | 
|  | 
| @@ -195,6 +219,13 @@ void CoordinationUnitImpl::RemoveParent(CoordinationUnitImpl* parent) { | 
| size_t parents_removed = parents_.erase(parent); | 
| DCHECK_EQ(1u, parents_removed); | 
|  | 
| +  // TODO(matthalp, oysteine) should this go before or | 
| +  // after RecalcCoordinationPolicy? | 
| +  for (auto listener : | 
| +       on_remove_parent_event_listeners_.GetListeners(parent->id().type)) { | 
| +    listener.Run(this, parent); | 
| +  } | 
| + | 
| RecalcCoordinationPolicy(); | 
| } | 
|  | 
| @@ -238,7 +269,8 @@ double CoordinationUnitImpl::GetCPUUsageForTesting() { | 
| return kCPUUsageUnmeasuredForTesting; | 
| } | 
|  | 
| -base::Value CoordinationUnitImpl::GetProperty(mojom::PropertyType property) { | 
| +base::Value CoordinationUnitImpl::GetProperty( | 
| +    mojom::PropertyType property) const { | 
| auto value_it = property_store_.find(property); | 
|  | 
| return value_it != property_store_.end() ? value_it->second : base::Value(); | 
| @@ -262,6 +294,18 @@ void CoordinationUnitImpl::SetProperty(mojom::PropertyType property, | 
| } | 
|  | 
| property_store_[property] = value; | 
| + | 
| +  for (auto listener : | 
| +       on_property_changed_event_listeners_.GetListeners(property)) { | 
| +    listener.Run(this, property); | 
| +  } | 
| +} | 
| + | 
| +void CoordinationUnitImpl::WillBeDestroyed() { | 
| +  for (auto listener : | 
| +       on_will_be_destroyed_event_listeners_.GetListenersWithoutAFilter()) { | 
| +    listener.Run(this); | 
| +  } | 
| } | 
|  | 
| }  // namespace resource_coordinator | 
|  |