Commit 6fa50ab2 authored by Peiyong Lin's avatar Peiyong Lin Committed by Commit Bot

[GRC] Implement TabDoneLoading signal.

This patch creates GRC TabSignalObserver for TabManager to get tab scoped
signals from GRC, implements TabDoneLoading signal and eventually sends it to
TabManager::WebContentsData, and changes network idle signal to be persisted.

TBR=japhet@chromium.org
BUG=730098

Change-Id: I5ba9be4365cc79b0d1e6f19e44ec93eeaf0408ee
Reviewed-on: https://chromium-review.googlesource.com/563832
Commit-Queue: lpy <lpy@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarZhen Wang <zhenw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#486880}
parent 29f9d1d7
...@@ -3405,6 +3405,8 @@ split_static_library("browser") { ...@@ -3405,6 +3405,8 @@ split_static_library("browser") {
"resource_coordinator/tab_manager.h", "resource_coordinator/tab_manager.h",
"resource_coordinator/tab_manager_delegate_chromeos.cc", "resource_coordinator/tab_manager_delegate_chromeos.cc",
"resource_coordinator/tab_manager_delegate_chromeos.h", "resource_coordinator/tab_manager_delegate_chromeos.h",
"resource_coordinator/tab_manager_grc_tab_signal_observer.cc",
"resource_coordinator/tab_manager_grc_tab_signal_observer.h",
"resource_coordinator/tab_manager_observer.cc", "resource_coordinator/tab_manager_observer.cc",
"resource_coordinator/tab_manager_observer.h", "resource_coordinator/tab_manager_observer.h",
"resource_coordinator/tab_manager_web_contents_data.cc", "resource_coordinator/tab_manager_web_contents_data.cc",
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
#include "chrome/browser/memory/oom_memory_details.h" #include "chrome/browser/memory/oom_memory_details.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/resource_coordinator/resource_coordinator_web_contents_observer.h"
#include "chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h"
#include "chrome/browser/resource_coordinator/tab_manager_observer.h" #include "chrome/browser/resource_coordinator/tab_manager_observer.h"
#include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h" #include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h"
#include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/sessions/session_restore.h"
...@@ -51,6 +53,7 @@ ...@@ -51,6 +53,7 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/page_importance_signals.h" #include "content/public/common/page_importance_signals.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "ash/multi_profile_uma.h" #include "ash/multi_profile_uma.h"
...@@ -149,6 +152,9 @@ TabManager::TabManager() ...@@ -149,6 +152,9 @@ TabManager::TabManager()
#endif #endif
browser_tab_strip_tracker_.Init(); browser_tab_strip_tracker_.Init();
session_restore_observer_.reset(new TabManagerSessionRestoreObserver(this)); session_restore_observer_.reset(new TabManagerSessionRestoreObserver(this));
if (resource_coordinator::IsResourceCoordinatorEnabled()) {
grc_tab_signal_observer_.reset(new GRCTabSignalObserver());
}
} }
TabManager::~TabManager() { TabManager::~TabManager() {
...@@ -848,6 +854,16 @@ void TabManager::TabInsertedAt(TabStripModel* tab_strip_model, ...@@ -848,6 +854,16 @@ void TabManager::TabInsertedAt(TabStripModel* tab_strip_model,
content::WebContents* contents, content::WebContents* contents,
int index, int index,
bool foreground) { bool foreground) {
// Gets CoordinationUnitID for this WebContents and adds it to
// GRCTabSignalObserver.
if (grc_tab_signal_observer_) {
auto* tab_resource_coordinator =
ResourceCoordinatorWebContentsObserver::FromWebContents(contents)
->tab_resource_coordinator();
grc_tab_signal_observer_->AssociateCoordinationUnitIDWithWebContents(
tab_resource_coordinator->id(), contents);
}
// Only interested in background tabs, as foreground tabs get taken care of by // Only interested in background tabs, as foreground tabs get taken care of by
// ActiveTabChanged. // ActiveTabChanged.
if (foreground) if (foreground)
...@@ -861,6 +877,20 @@ void TabManager::TabInsertedAt(TabStripModel* tab_strip_model, ...@@ -861,6 +877,20 @@ void TabManager::TabInsertedAt(TabStripModel* tab_strip_model,
GetTimeToPurge(min_time_to_purge_, max_time_to_purge_)); GetTimeToPurge(min_time_to_purge_, max_time_to_purge_));
} }
void TabManager::TabClosingAt(TabStripModel* tab_strip_model,
content::WebContents* contents,
int index) {
// Gets CoordinationUnitID for this WebContents and removes it from
// GRCTabSignalObserver.
if (!grc_tab_signal_observer_)
return;
auto* tab_resource_coordinator =
ResourceCoordinatorWebContentsObserver::FromWebContents(contents)
->tab_resource_coordinator();
grc_tab_signal_observer_->RemoveCoordinationUnitID(
tab_resource_coordinator->id());
}
void TabManager::OnBrowserSetLastActive(Browser* browser) { void TabManager::OnBrowserSetLastActive(Browser* browser) {
// Reload the active tab in |browser| if it is discarded. // Reload the active tab in |browser| if it is discarded.
content::WebContents* contents = content::WebContents* contents =
......
...@@ -72,6 +72,8 @@ class TabManagerDelegate; ...@@ -72,6 +72,8 @@ class TabManagerDelegate;
class TabManager : public TabStripModelObserver, class TabManager : public TabStripModelObserver,
public chrome::BrowserListObserver { public chrome::BrowserListObserver {
public: public:
// Forward declaration of tab signal observer.
class GRCTabSignalObserver;
// Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY. // Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY.
class WebContentsData; class WebContentsData;
...@@ -326,6 +328,9 @@ class TabManager : public TabStripModelObserver, ...@@ -326,6 +328,9 @@ class TabManager : public TabStripModelObserver,
content::WebContents* contents, content::WebContents* contents,
int index, int index,
bool foreground) override; bool foreground) override;
void TabClosingAt(TabStripModel* tab_strip_model,
content::WebContents* contents,
int index) override;
// BrowserListObserver overrides. // BrowserListObserver overrides.
void OnBrowserSetLastActive(Browser* browser) override; void OnBrowserSetLastActive(Browser* browser) override;
...@@ -468,6 +473,9 @@ class TabManager : public TabStripModelObserver, ...@@ -468,6 +473,9 @@ class TabManager : public TabStripModelObserver,
// is brought to foreground. // is brought to foreground.
std::set<content::WebContents*> loading_contents_; std::set<content::WebContents*> loading_contents_;
// GRC tab signal observer, receives tab scoped signal from GRC.
std::unique_ptr<GRCTabSignalObserver> grc_tab_signal_observer_;
// Weak pointer factory used for posting delayed tasks. // Weak pointer factory used for posting delayed tasks.
base::WeakPtrFactory<TabManager> weak_ptr_factory_; base::WeakPtrFactory<TabManager> weak_ptr_factory_;
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/resource_coordinator/tab_manager_grc_tab_signal_observer.h"
#include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h"
#include "content/public/common/service_manager_connection.h"
#include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
#include "services/resource_coordinator/public/interfaces/service_constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
namespace resource_coordinator {
TabManager::GRCTabSignalObserver::GRCTabSignalObserver() : binding_(this) {
service_manager::Connector* connector =
content::ServiceManagerConnection::GetForProcess()->GetConnector();
mojom::TabSignalGeneratorPtr tab_signal_generator_ptr;
connector->BindInterface(mojom::kServiceName,
mojo::MakeRequest(&tab_signal_generator_ptr));
mojom::TabSignalObserverPtr tab_signal_observer_ptr;
binding_.Bind(mojo::MakeRequest(&tab_signal_observer_ptr));
tab_signal_generator_ptr->AddObserver(std::move(tab_signal_observer_ptr));
}
TabManager::GRCTabSignalObserver::~GRCTabSignalObserver() = default;
void TabManager::GRCTabSignalObserver::OnEventReceived(
const CoordinationUnitID& cu_id,
mojom::TabEvent event) {
if (event == mojom::TabEvent::kDoneLoading) {
auto web_contents_iter = cu_id_web_contents_map_.find(cu_id);
if (web_contents_iter == cu_id_web_contents_map_.end())
return;
auto* web_contents_data =
TabManager::WebContentsData::FromWebContents(web_contents_iter->second);
web_contents_data->DoneLoading();
}
}
void TabManager::GRCTabSignalObserver::
AssociateCoordinationUnitIDWithWebContents(
const CoordinationUnitID& cu_id,
content::WebContents* web_contents) {
cu_id_web_contents_map_[cu_id] = web_contents;
}
void TabManager::GRCTabSignalObserver::RemoveCoordinationUnitID(
const CoordinationUnitID& cu_id) {
cu_id_web_contents_map_.erase(cu_id);
}
} // namespace resource_coordinator
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_GRC_TAB_SIGNAL_OBSERVER_H_
#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_GRC_TAB_SIGNAL_OBSERVER_H_
#include "base/macros.h"
#include "chrome/browser/resource_coordinator/tab_manager.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/resource_coordinator/public/interfaces/tab_signal.mojom.h"
namespace content {
class WebContents;
}
namespace resource_coordinator {
// Implementation of resource_coordinator::mojom::TabSignalObserver,
// observer constructs a mojo channel to TabSignalGenerator in GRC, passes an
// interface pointer to TabSignalGenerator, and receives tab scoped signals from
// TabSignalGenerator once a signal is generated.
class TabManager::GRCTabSignalObserver : public mojom::TabSignalObserver {
public:
GRCTabSignalObserver();
~GRCTabSignalObserver() override;
// mojom::TabSignalObserver implementation.
void OnEventReceived(const CoordinationUnitID& cu_id,
mojom::TabEvent event) override;
void AssociateCoordinationUnitIDWithWebContents(
const CoordinationUnitID& cu_id,
content::WebContents* web_contents);
void RemoveCoordinationUnitID(const CoordinationUnitID& cu_id);
private:
mojo::Binding<mojom::TabSignalObserver> binding_;
std::map<CoordinationUnitID, content::WebContents*> cu_id_web_contents_map_;
DISALLOW_COPY_AND_ASSIGN(GRCTabSignalObserver);
};
} // namespace resource_coordinator
#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_GRC_TAB_SIGNAL_OBSERVER_H_
...@@ -61,6 +61,9 @@ class TabManager::WebContentsData ...@@ -61,6 +61,9 @@ class TabManager::WebContentsData
content::NavigationHandle* navigation_handle) override; content::NavigationHandle* navigation_handle) override;
void WebContentsDestroyed() override; void WebContentsDestroyed() override;
// Tab signal received from GRC.
void DoneLoading() {}
// Returns true if the tab has been discarded to save memory. // Returns true if the tab has been discarded to save memory.
bool IsDiscarded(); bool IsDiscarded();
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
"face_detection", "face_detection",
"text_detection" "text_detection"
], ],
"resource_coordinator": [ "coordination_unit", "service_callbacks" ], "resource_coordinator": [ "coordination_unit", "service_callbacks", "tab_signal" ],
"video_capture": [ "capture", "tests" ] "video_capture": [ "capture", "tests" ]
} }
}, },
......
...@@ -26,8 +26,8 @@ source_set("lib") { ...@@ -26,8 +26,8 @@ source_set("lib") {
"coordination_unit/frame_coordination_unit_impl.h", "coordination_unit/frame_coordination_unit_impl.h",
"coordination_unit/process_coordination_unit_impl.cc", "coordination_unit/process_coordination_unit_impl.cc",
"coordination_unit/process_coordination_unit_impl.h", "coordination_unit/process_coordination_unit_impl.h",
"coordination_unit/tab_signal_generator.cc", "coordination_unit/tab_signal_generator_impl.cc",
"coordination_unit/tab_signal_generator.h", "coordination_unit/tab_signal_generator_impl.h",
"coordination_unit/web_contents_coordination_unit_impl.cc", "coordination_unit/web_contents_coordination_unit_impl.cc",
"coordination_unit/web_contents_coordination_unit_impl.h", "coordination_unit/web_contents_coordination_unit_impl.h",
"memory_instrumentation/coordinator_impl.cc", "memory_instrumentation/coordinator_impl.cc",
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/resource_coordinator/coordination_unit/coordination_unit_graph_observer.h" #include "services/resource_coordinator/coordination_unit/coordination_unit_graph_observer.h"
#include "services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h"
#include "services/resource_coordinator/public/cpp/coordination_unit_id.h" #include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
namespace resource_coordinator { namespace resource_coordinator {
...@@ -29,6 +30,13 @@ CUIDMap& g_cu_map() { ...@@ -29,6 +30,13 @@ CUIDMap& g_cu_map() {
} // namespace } // namespace
// static
const FrameCoordinationUnitImpl* CoordinationUnitImpl::ToFrameCoordinationUnit(
const CoordinationUnitImpl* coordination_unit) {
DCHECK(coordination_unit->id().type == CoordinationUnitType::kFrame);
return static_cast<const FrameCoordinationUnitImpl*>(coordination_unit);
}
CoordinationUnitImpl::CoordinationUnitImpl( CoordinationUnitImpl::CoordinationUnitImpl(
const CoordinationUnitID& id, const CoordinationUnitID& id,
std::unique_ptr<service_manager::ServiceContextRef> service_ref) std::unique_ptr<service_manager::ServiceContextRef> service_ref)
...@@ -99,6 +107,7 @@ void CoordinationUnitImpl::RecalcCoordinationPolicy() { ...@@ -99,6 +107,7 @@ void CoordinationUnitImpl::RecalcCoordinationPolicy() {
} }
void CoordinationUnitImpl::SendEvent(mojom::EventPtr event) { void CoordinationUnitImpl::SendEvent(mojom::EventPtr event) {
// TODO(crbug.com/691886) Consider removing the following code.
switch (event->type) { switch (event->type) {
case mojom::EventType::kOnWebContentsShown: case mojom::EventType::kOnWebContentsShown:
state_flags_[kTabVisible] = true; state_flags_[kTabVisible] = true;
...@@ -112,9 +121,6 @@ void CoordinationUnitImpl::SendEvent(mojom::EventPtr event) { ...@@ -112,9 +121,6 @@ void CoordinationUnitImpl::SendEvent(mojom::EventPtr event) {
case mojom::EventType::kOnProcessAudioStopped: case mojom::EventType::kOnProcessAudioStopped:
state_flags_[kAudioPlaying] = false; state_flags_[kAudioPlaying] = false;
break; break;
case mojom::EventType::kOnLocalFrameNetworkIdle:
state_flags_[kNetworkIdle] = true;
break;
case mojom::EventType::kTestEvent: case mojom::EventType::kTestEvent:
state_flags_[kTestState] = true; state_flags_[kTestState] = true;
break; break;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
namespace resource_coordinator { namespace resource_coordinator {
class CoordinationUnitGraphObserver; class CoordinationUnitGraphObserver;
class FrameCoordinationUnitImpl;
class CoordinationUnitImpl : public mojom::CoordinationUnit { class CoordinationUnitImpl : public mojom::CoordinationUnit {
public: public:
...@@ -31,6 +32,9 @@ class CoordinationUnitImpl : public mojom::CoordinationUnit { ...@@ -31,6 +32,9 @@ class CoordinationUnitImpl : public mojom::CoordinationUnit {
std::unique_ptr<service_manager::ServiceContextRef> service_ref); std::unique_ptr<service_manager::ServiceContextRef> service_ref);
~CoordinationUnitImpl() override; ~CoordinationUnitImpl() override;
static const FrameCoordinationUnitImpl* ToFrameCoordinationUnit(
const CoordinationUnitImpl* coordination_unit);
// Overridden from mojom::CoordinationUnit: // Overridden from mojom::CoordinationUnit:
void SendEvent(mojom::EventPtr event) override; void SendEvent(mojom::EventPtr event) override;
void GetID(const GetIDCallback& callback) override; void GetID(const GetIDCallback& callback) override;
......
...@@ -37,4 +37,12 @@ FrameCoordinationUnitImpl::GetAssociatedCoordinationUnitsOfType( ...@@ -37,4 +37,12 @@ FrameCoordinationUnitImpl::GetAssociatedCoordinationUnitsOfType(
} }
} }
bool FrameCoordinationUnitImpl::IsMainFrame() const {
for (auto* parent : parents_) {
if (parent->id().type == CoordinationUnitType::kFrame)
return false;
}
return true;
}
} // namespace resource_coordinator } // namespace resource_coordinator
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
namespace resource_coordinator { namespace resource_coordinator {
struct CoordinationUnitID;
class FrameCoordinationUnitImpl : public CoordinationUnitImpl { class FrameCoordinationUnitImpl : public CoordinationUnitImpl {
public: public:
FrameCoordinationUnitImpl( FrameCoordinationUnitImpl(
...@@ -25,6 +23,8 @@ class FrameCoordinationUnitImpl : public CoordinationUnitImpl { ...@@ -25,6 +23,8 @@ class FrameCoordinationUnitImpl : public CoordinationUnitImpl {
std::set<CoordinationUnitImpl*> GetAssociatedCoordinationUnitsOfType( std::set<CoordinationUnitImpl*> GetAssociatedCoordinationUnitsOfType(
CoordinationUnitType type) override; CoordinationUnitType type) override;
bool IsMainFrame() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(FrameCoordinationUnitImpl); DISALLOW_COPY_AND_ASSIGN(FrameCoordinationUnitImpl);
}; };
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/resource_coordinator/coordination_unit/tab_signal_generator.h"
#include "services/resource_coordinator/coordination_unit/coordination_unit_impl.h"
namespace resource_coordinator {
TabSignalGenerator::TabSignalGenerator() = default;
TabSignalGenerator::~TabSignalGenerator() = default;
bool TabSignalGenerator::ShouldObserve(
const CoordinationUnitImpl* coordination_unit) {
return coordination_unit->id().type == CoordinationUnitType::kWebContents;
}
} // namespace resource_coordinator
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_TAB_SIGNAL_GENERATOR_H_
#define SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_TAB_SIGNAL_GENERATOR_H_
#include "base/macros.h"
#include "services/resource_coordinator/coordination_unit/coordination_unit_graph_observer.h"
namespace resource_coordinator {
class CoordinationUnitImpl;
// The TabSignalGenerator is a unified |CoordinationUnitGraphObserver| for
// calculating and emitting tab-scoped signals. Nonetheless, the observer
// has access to the whole coordination unit graph and thus can utilize
// the information contained within the entire graph to generate the signals.
class TabSignalGenerator : public CoordinationUnitGraphObserver {
public:
TabSignalGenerator();
~TabSignalGenerator() override;
bool ShouldObserve(const CoordinationUnitImpl* coordination_unit) override;
private:
DISALLOW_COPY_AND_ASSIGN(TabSignalGenerator);
};
} // namespace resource_coordinator
#endif // SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_TAB_SIGNAL_GENERATOR_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/resource_coordinator/coordination_unit/tab_signal_generator_impl.h"
#include "services/resource_coordinator/coordination_unit/coordination_unit_impl.h"
#include "services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h"
#include "services/resource_coordinator/coordination_unit/web_contents_coordination_unit_impl.h"
namespace resource_coordinator {
#define DISPATCH_TAB_SIGNAL(observers, METHOD, cu, ...) \
observers.ForAllPtrs([cu](mojom::TabSignalObserver* observer) { \
observer->METHOD(cu->id(), __VA_ARGS__); \
});
TabSignalGeneratorImpl::TabSignalGeneratorImpl() = default;
TabSignalGeneratorImpl::~TabSignalGeneratorImpl() = default;
void TabSignalGeneratorImpl::AddObserver(mojom::TabSignalObserverPtr observer) {
observers_.AddPtr(std::move(observer));
}
bool TabSignalGeneratorImpl::ShouldObserve(
const CoordinationUnitImpl* coordination_unit) {
auto coordination_unit_type = coordination_unit->id().type;
return coordination_unit_type == CoordinationUnitType::kWebContents ||
coordination_unit_type == CoordinationUnitType::kFrame;
}
void TabSignalGeneratorImpl::OnPropertyChanged(
const CoordinationUnitImpl* coordination_unit,
const mojom::PropertyType property_type,
const base::Value& value) {
if (coordination_unit->id().type == CoordinationUnitType::kFrame) {
OnFramePropertyChanged(
CoordinationUnitImpl::ToFrameCoordinationUnit(coordination_unit),
property_type, value);
}
}
void TabSignalGeneratorImpl::BindToInterface(
const service_manager::BindSourceInfo& source_info,
resource_coordinator::mojom::TabSignalGeneratorRequest request) {
bindings_.AddBinding(this, std::move(request));
}
void TabSignalGeneratorImpl::OnFramePropertyChanged(
const FrameCoordinationUnitImpl* coordination_unit,
const mojom::PropertyType property_type,
const base::Value& value) {
if (property_type == mojom::PropertyType::kNetworkIdle) {
// Ignore when the signal doesn't come from main frame.
if (!coordination_unit->IsMainFrame())
return;
// TODO(lpy) Combine CPU usage or long task idleness signal.
for (auto* parent : coordination_unit->parents()) {
if (parent->id().type != CoordinationUnitType::kWebContents)
continue;
DISPATCH_TAB_SIGNAL(observers_, OnEventReceived, parent,
mojom::TabEvent::kDoneLoading);
break;
}
}
}
} // namespace resource_coordinator
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_TAB_SIGNAL_GENERATOR_IMPL_H_
#define SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_TAB_SIGNAL_GENERATOR_IMPL_H_
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/resource_coordinator/coordination_unit/coordination_unit_graph_observer.h"
#include "services/resource_coordinator/public/interfaces/tab_signal.mojom.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
namespace resource_coordinator {
class CoordinationUnitImpl;
class FrameCoordinationUnitImpl;
// The TabSignalGenerator is a dedicated |CoordinationUnitGraphObserver| for
// calculating and emitting tab-scoped signals. This observer observes Tab
// CoordinationUnits and Frame CoordinationUnits, utilize information from the
// graph and generate tab level signals.
class TabSignalGeneratorImpl : public CoordinationUnitGraphObserver,
public mojom::TabSignalGenerator {
public:
TabSignalGeneratorImpl();
~TabSignalGeneratorImpl() override;
// mojom::SignalGenerator implementation.
void AddObserver(mojom::TabSignalObserverPtr observer) override;
// CoordinationUnitGraphObserver implementation.
bool ShouldObserve(const CoordinationUnitImpl* coordination_unit) override;
void OnPropertyChanged(const CoordinationUnitImpl* coordination_unit,
const mojom::PropertyType property_type,
const base::Value& value) override;
void BindToInterface(
const service_manager::BindSourceInfo& source_info,
resource_coordinator::mojom::TabSignalGeneratorRequest request);
private:
void OnFramePropertyChanged(
const FrameCoordinationUnitImpl* coordination_unit,
const mojom::PropertyType property_type,
const base::Value& value);
mojo::BindingSet<mojom::TabSignalGenerator> bindings_;
mojo::InterfacePtrSet<mojom::TabSignalObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(TabSignalGeneratorImpl);
};
} // namespace resource_coordinator
#endif // SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_TAB_SIGNAL_GENERATOR_IMPL_H_
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"provides": { "provides": {
"coordination_unit": [ "resource_coordinator::mojom::CoordinationUnitProvider" ], "coordination_unit": [ "resource_coordinator::mojom::CoordinationUnitProvider" ],
"service_callbacks": [ "resource_coordinator::mojom::ServiceCallbacks" ], "service_callbacks": [ "resource_coordinator::mojom::ServiceCallbacks" ],
"tab_signal": [ "resource_coordinator::mojom::TabSignalGenerator" ],
"tests": [ "*" ] "tests": [ "*" ]
}, },
"requires": { "requires": {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_ID_H_ #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_ID_H_
#include <string> #include <string>
#include <tuple>
#include "services/resource_coordinator/public/cpp/coordination_unit_types.h" #include "services/resource_coordinator/public/cpp/coordination_unit_types.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h" #include "services/resource_coordinator/public/cpp/resource_coordinator_export.h"
...@@ -29,6 +30,10 @@ struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT CoordinationUnitID { ...@@ -29,6 +30,10 @@ struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT CoordinationUnitID {
return id == b.id && type == b.type; return id == b.id && type == b.type;
} }
bool operator<(const CoordinationUnitID& b) const {
return std::tie(id, type) < std::tie(b.id, b.type);
}
CoordinationUnitTypeId id; CoordinationUnitTypeId id;
CoordinationUnitType type; CoordinationUnitType type;
}; };
......
...@@ -11,3 +11,11 @@ const base::Feature kGlobalResourceCoordinator{ ...@@ -11,3 +11,11 @@ const base::Feature kGlobalResourceCoordinator{
"GlobalResourceCoordinator", base::FEATURE_DISABLED_BY_DEFAULT}; "GlobalResourceCoordinator", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace features } // namespace features
namespace resource_coordinator {
bool IsResourceCoordinatorEnabled() {
return base::FeatureList::IsEnabled(features::kGlobalResourceCoordinator);
}
} // namespace resource_coordinator
...@@ -20,4 +20,11 @@ extern const SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT base::Feature ...@@ -20,4 +20,11 @@ extern const SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT base::Feature
} // namespace features } // namespace features
namespace resource_coordinator {
bool SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
IsResourceCoordinatorEnabled();
} // namespace resource_coordinator
#endif // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_FEATURES_H_ #endif // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_FEATURES_H_
...@@ -51,6 +51,7 @@ void ResourceCoordinatorInterface::ConnectToService( ...@@ -51,6 +51,7 @@ void ResourceCoordinatorInterface::ConnectToService(
const CoordinationUnitID& cu_id) { const CoordinationUnitID& cu_id) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(connector); DCHECK(connector);
cu_id_ = cu_id;
mojom::CoordinationUnitProviderPtr provider; mojom::CoordinationUnitProviderPtr provider;
connector->BindInterface(mojom::kServiceName, mojo::MakeRequest(&provider)); connector->BindInterface(mojom::kServiceName, mojo::MakeRequest(&provider));
......
...@@ -43,6 +43,7 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ...@@ -43,6 +43,7 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
std::unique_ptr<base::Value> value); std::unique_ptr<base::Value> value);
void AddChild(const ResourceCoordinatorInterface& child); void AddChild(const ResourceCoordinatorInterface& child);
void RemoveChild(const ResourceCoordinatorInterface& child); void RemoveChild(const ResourceCoordinatorInterface& child);
CoordinationUnitID id() const { return cu_id_; }
private: private:
void ConnectToService(service_manager::Connector* connector, void ConnectToService(service_manager::Connector* connector,
...@@ -51,6 +52,7 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT ...@@ -51,6 +52,7 @@ class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
void RemoveChildByID(const CoordinationUnitID& child_id); void RemoveChildByID(const CoordinationUnitID& child_id);
mojom::CoordinationUnitPtr service_; mojom::CoordinationUnitPtr service_;
CoordinationUnitID cu_id_;
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
......
...@@ -15,6 +15,7 @@ mojom("interfaces_internal") { ...@@ -15,6 +15,7 @@ mojom("interfaces_internal") {
"memory_instrumentation/memory_instrumentation.mojom", "memory_instrumentation/memory_instrumentation.mojom",
"service_callbacks.mojom", "service_callbacks.mojom",
"service_constants.mojom", "service_constants.mojom",
"tab_signal.mojom",
"tracing/tracing.mojom", "tracing/tracing.mojom",
"tracing/tracing_constants.mojom", "tracing/tracing_constants.mojom",
] ]
......
...@@ -35,6 +35,7 @@ interface CoordinationPolicyCallback { ...@@ -35,6 +35,7 @@ interface CoordinationPolicyCallback {
enum PropertyType { enum PropertyType {
kTest, kTest,
kCPUUsage, kCPUUsage,
kNetworkIdle,
kVisible, kVisible,
}; };
......
...@@ -7,12 +7,14 @@ module resource_coordinator.mojom; ...@@ -7,12 +7,14 @@ module resource_coordinator.mojom;
enum EventType { enum EventType {
kTestEvent, kTestEvent,
kOnNavigationCommit, kOnNavigationCommit,
// WebContents event types.
kOnWebContentsShown, kOnWebContentsShown,
kOnWebContentsHidden, kOnWebContentsHidden,
kOnRendererFrameCreated,
// Process event types.
kOnProcessAudioStarted, kOnProcessAudioStarted,
kOnProcessAudioStopped, kOnProcessAudioStopped,
kOnLocalFrameNetworkIdle,
}; };
struct Event { struct Event {
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module resource_coordinator.mojom;
import "coordination_unit.mojom";
import "mojo/common/values.mojom";
// Event signal scoped to a tab.
enum TabEvent {
kDoneLoading,
};
// A TabSignalObserver implementation receives tab-scoped signal from
// TabSignalGenerator.
// Any interested party that needs to observe tab-scoped signal from GRC must
// implement this interface, construct mojo channel to the implementation, and
// pass the interface pointer of mojo channel to TabSignalGenerator through
// TabSignalGenerator::AddObserver.
interface TabSignalObserver {
OnEventReceived(CoordinationUnitID cu_id, TabEvent event);
};
// A TabSignalGenerator implementation will be implemented inside GRC to observe
// signals from Coordination Units, generate tab-scoped signals, sends signals
// to TabSignalObserver implementations.
// There will be only one TabSignalGenerator implementation.
interface TabSignalGenerator {
AddObserver(TabSignalObserver observer);
};
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <utility> #include <utility>
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "services/resource_coordinator/coordination_unit/tab_signal_generator.h" #include "services/resource_coordinator/coordination_unit/tab_signal_generator_impl.h"
#include "services/resource_coordinator/service_callbacks_impl.h" #include "services/resource_coordinator/service_callbacks_impl.h"
#include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_context.h"
...@@ -17,12 +17,7 @@ std::unique_ptr<service_manager::Service> ResourceCoordinatorService::Create() { ...@@ -17,12 +17,7 @@ std::unique_ptr<service_manager::Service> ResourceCoordinatorService::Create() {
auto resource_coordinator_service = auto resource_coordinator_service =
base::MakeUnique<ResourceCoordinatorService>(); base::MakeUnique<ResourceCoordinatorService>();
// Register new |CoordinationUnitGraphObserver| implementations here. return resource_coordinator_service;
resource_coordinator_service->coordination_unit_manager()->RegisterObserver(
base::MakeUnique<TabSignalGenerator>());
return std::unique_ptr<service_manager::Service>(
resource_coordinator_service.release());
} }
ResourceCoordinatorService::ResourceCoordinatorService() ResourceCoordinatorService::ResourceCoordinatorService()
...@@ -39,6 +34,14 @@ void ResourceCoordinatorService::OnStart() { ...@@ -39,6 +34,14 @@ void ResourceCoordinatorService::OnStart() {
base::Unretained(ref_factory_.get()), base::Unretained(ref_factory_.get()),
base::Unretained(this))); base::Unretained(this)));
// Register new |CoordinationUnitGraphObserver| implementations here.
auto tab_signal_generator_impl = base::MakeUnique<TabSignalGeneratorImpl>();
registry_.AddInterface(
base::Bind(&TabSignalGeneratorImpl::BindToInterface,
base::Unretained(tab_signal_generator_impl.get())));
coordination_unit_manager_.RegisterObserver(
std::move(tab_signal_generator_impl));
coordination_unit_manager_.OnStart(&registry_, ref_factory_.get()); coordination_unit_manager_.OnStart(&registry_, ref_factory_.get());
} }
......
...@@ -73,8 +73,8 @@ void NetworkQuietDetector::NetworkQuietTimerFired(TimerBase*) { ...@@ -73,8 +73,8 @@ void NetworkQuietDetector::NetworkQuietTimerFired(TimerBase*) {
auto frame_resource_coordinator = auto frame_resource_coordinator =
GetSupplementable()->GetFrame()->GetFrameResourceCoordinator(); GetSupplementable()->GetFrame()->GetFrameResourceCoordinator();
if (frame_resource_coordinator) { if (frame_resource_coordinator) {
frame_resource_coordinator->SendEvent( frame_resource_coordinator->SetProperty(
resource_coordinator::mojom::EventType::kOnLocalFrameNetworkIdle); resource_coordinator::mojom::PropertyType::kNetworkIdle, true);
} }
} }
......
...@@ -33,22 +33,14 @@ FrameResourceCoordinator::FrameResourceCoordinator( ...@@ -33,22 +33,14 @@ FrameResourceCoordinator::FrameResourceCoordinator(
service_.set_connection_error_handler( service_.set_connection_error_handler(
ConvertToBaseCallback(WTF::Bind(&onConnectionError))); ConvertToBaseCallback(WTF::Bind(&onConnectionError)));
resource_coordinator::mojom::blink::EventPtr event =
resource_coordinator::mojom::blink::Event::New();
event->type = resource_coordinator::mojom::EventType::kOnRendererFrameCreated;
service_->SendEvent(std::move(event));
} }
FrameResourceCoordinator::~FrameResourceCoordinator() = default; FrameResourceCoordinator::~FrameResourceCoordinator() = default;
void FrameResourceCoordinator::SendEvent( void FrameResourceCoordinator::SetProperty(
const resource_coordinator::mojom::blink::EventType& event_type) { const resource_coordinator::mojom::blink::PropertyType property_type,
resource_coordinator::mojom::blink::EventPtr event = const bool value) {
resource_coordinator::mojom::blink::Event::New(); service_->SetProperty(property_type, base::MakeUnique<base::Value>(value));
event->type = event_type;
service_->SendEvent(std::move(event));
} }
DEFINE_TRACE(FrameResourceCoordinator) {} DEFINE_TRACE(FrameResourceCoordinator) {}
......
...@@ -22,7 +22,8 @@ class PLATFORM_EXPORT FrameResourceCoordinator final ...@@ -22,7 +22,8 @@ class PLATFORM_EXPORT FrameResourceCoordinator final
static bool IsEnabled(); static bool IsEnabled();
static FrameResourceCoordinator* Create(service_manager::InterfaceProvider*); static FrameResourceCoordinator* Create(service_manager::InterfaceProvider*);
virtual ~FrameResourceCoordinator(); virtual ~FrameResourceCoordinator();
void SendEvent(const resource_coordinator::mojom::blink::EventType&); void SetProperty(const resource_coordinator::mojom::blink::PropertyType,
const bool);
DECLARE_TRACE(); DECLARE_TRACE();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment