Commit 7f21b029 authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

RC: Pass the OnNonPersistentNotificationCreated signal to c/b/rc

This forwards the |kNonPersistentNotificationCreated| events received
in services/resource_coordinator/ to the page signal observer on the
browser side (c/b/rc). Non-persistent notifications are web
notifications created by a page, they require the page to be alive to
be created (persistent notifications are created by service workers and
don't rely on the page to be alive)

These events will be recorded in the local site characteristics
database in a further CL. We need to consider potential usage of
non-persistent web notifications before proactively discarding a tab to
make sure that we don't discard a tab that could try to communicate
with the user via non-persistent web notifications.

Bug: 773382
Change-Id: I0245cd4514541a2f70b547d5ce9fab0e633ddf94
Reviewed-on: https://chromium-review.googlesource.com/1068665Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#562539}
parent 47070783
...@@ -65,6 +65,15 @@ void PageSignalReceiver::SetLifecycleState(const CoordinationUnitID& cu_id, ...@@ -65,6 +65,15 @@ void PageSignalReceiver::SetLifecycleState(const CoordinationUnitID& cu_id,
observer.OnLifecycleStateChanged(web_contents_iter->second, state); observer.OnLifecycleStateChanged(web_contents_iter->second, state);
} }
void PageSignalReceiver::NotifyNonPersistentNotificationCreated(
const CoordinationUnitID& cu_id) {
auto web_contents_iter = cu_id_web_contents_map_.find(cu_id);
if (web_contents_iter == cu_id_web_contents_map_.end())
return;
for (auto& observer : observers_)
observer.OnNonPersistentNotificationCreated(web_contents_iter->second);
}
void PageSignalReceiver::AddObserver(PageSignalObserver* observer) { void PageSignalReceiver::AddObserver(PageSignalObserver* observer) {
// When PageSignalReceiver starts to have observer, construct the mojo // When PageSignalReceiver starts to have observer, construct the mojo
// channel. // channel.
......
...@@ -30,6 +30,8 @@ class PageSignalObserver { ...@@ -30,6 +30,8 @@ class PageSignalObserver {
base::TimeDelta duration) {} base::TimeDelta duration) {}
virtual void OnLifecycleStateChanged(content::WebContents* web_contents, virtual void OnLifecycleStateChanged(content::WebContents* web_contents,
mojom::LifecycleState state) {} mojom::LifecycleState state) {}
virtual void OnNonPersistentNotificationCreated(
content::WebContents* web_contents) {}
}; };
// Implementation of resource_coordinator::mojom::PageSignalReceiver. // Implementation of resource_coordinator::mojom::PageSignalReceiver.
...@@ -54,6 +56,8 @@ class PageSignalReceiver : public mojom::PageSignalReceiver { ...@@ -54,6 +56,8 @@ class PageSignalReceiver : public mojom::PageSignalReceiver {
base::TimeDelta duration) override; base::TimeDelta duration) override;
void SetLifecycleState(const CoordinationUnitID& cu_id, void SetLifecycleState(const CoordinationUnitID& cu_id,
mojom::LifecycleState) override; mojom::LifecycleState) override;
void NotifyNonPersistentNotificationCreated(
const CoordinationUnitID& cu_id) override;
void AddObserver(PageSignalObserver* observer); void AddObserver(PageSignalObserver* observer);
void RemoveObserver(PageSignalObserver* observer); void RemoveObserver(PageSignalObserver* observer);
......
...@@ -48,4 +48,10 @@ void TabManager::ResourceCoordinatorSignalObserver:: ...@@ -48,4 +48,10 @@ void TabManager::ResourceCoordinatorSignalObserver::
->RecordExpectedTaskQueueingDuration(web_contents, duration); ->RecordExpectedTaskQueueingDuration(web_contents, duration);
} }
void TabManager::ResourceCoordinatorSignalObserver::
OnNonPersistentNotificationCreated(content::WebContents* web_contents) {
// TODO(sebmarchand): Add the wiring to forward this signal where it should be
// used.
}
} // namespace resource_coordinator } // namespace resource_coordinator
...@@ -25,6 +25,8 @@ class TabManager::ResourceCoordinatorSignalObserver ...@@ -25,6 +25,8 @@ class TabManager::ResourceCoordinatorSignalObserver
void OnPageAlmostIdle(content::WebContents* web_contents) override; void OnPageAlmostIdle(content::WebContents* web_contents) override;
void OnExpectedTaskQueueingDurationSet(content::WebContents* web_contents, void OnExpectedTaskQueueingDurationSet(content::WebContents* web_contents,
base::TimeDelta duration) override; base::TimeDelta duration) override;
void OnNonPersistentNotificationCreated(
content::WebContents* web_contents) override;
private: private:
DISALLOW_COPY_AND_ASSIGN(ResourceCoordinatorSignalObserver); DISALLOW_COPY_AND_ASSIGN(ResourceCoordinatorSignalObserver);
......
...@@ -77,7 +77,7 @@ void PageSignalGeneratorImpl::OnCoordinationUnitCreated( ...@@ -77,7 +77,7 @@ void PageSignalGeneratorImpl::OnCoordinationUnitCreated(
// Create page data exists for this Page CU. // Create page data exists for this Page CU.
auto* page_cu = PageCoordinationUnitImpl::FromCoordinationUnitBase(cu); auto* page_cu = PageCoordinationUnitImpl::FromCoordinationUnitBase(cu);
DCHECK(!base::ContainsKey(page_data_, page_cu)); // No data should exist yet. DCHECK(!base::ContainsKey(page_data_, page_cu)); // No data should exist yet.
page_data_[page_cu].load_idle_state = kLoadingNotStarted; page_data_[page_cu].load_idle_state = kLoadingNotStarted;
} }
...@@ -143,6 +143,20 @@ void PageSignalGeneratorImpl::OnProcessPropertyChanged( ...@@ -143,6 +143,20 @@ void PageSignalGeneratorImpl::OnProcessPropertyChanged(
} }
} }
void PageSignalGeneratorImpl::OnFrameEventReceived(
const FrameCoordinationUnitImpl* frame_cu,
const mojom::Event event) {
if (event != mojom::Event::kNonPersistentNotificationCreated)
return;
auto* page_cu = frame_cu->GetPageCoordinationUnit();
if (!page_cu)
return;
DISPATCH_PAGE_SIGNAL(receivers_, NotifyNonPersistentNotificationCreated,
page_cu->id());
}
void PageSignalGeneratorImpl::OnPageEventReceived( void PageSignalGeneratorImpl::OnPageEventReceived(
const PageCoordinationUnitImpl* page_cu, const PageCoordinationUnitImpl* page_cu,
const mojom::Event event) { const mojom::Event event) {
...@@ -334,11 +348,10 @@ bool PageSignalGeneratorImpl::IsIdling( ...@@ -334,11 +348,10 @@ bool PageSignalGeneratorImpl::IsIdling(
// associated with this page's main frame actually being low. In the case // associated with this page's main frame actually being low. In the case
// of session restore this is mitigated by having a timeout while waiting for // of session restore this is mitigated by having a timeout while waiting for
// this signal. // this signal.
return return main_frame_cu->GetPropertyOrDefault(
main_frame_cu->GetPropertyOrDefault( mojom::PropertyType::kNetworkAlmostIdle, 0u) &&
mojom::PropertyType::kNetworkAlmostIdle, 0u) && process_cu->GetPropertyOrDefault(
process_cu->GetPropertyOrDefault( mojom::PropertyType::kMainThreadTaskLoadIsLow, 0u);
mojom::PropertyType::kMainThreadTaskLoadIsLow, 0u);
} }
} // namespace resource_coordinator } // namespace resource_coordinator
...@@ -60,6 +60,8 @@ class PageSignalGeneratorImpl : public CoordinationUnitGraphObserver, ...@@ -60,6 +60,8 @@ class PageSignalGeneratorImpl : public CoordinationUnitGraphObserver,
void OnProcessPropertyChanged(const ProcessCoordinationUnitImpl* process_cu, void OnProcessPropertyChanged(const ProcessCoordinationUnitImpl* process_cu,
const mojom::PropertyType property_type, const mojom::PropertyType property_type,
int64_t value) override; int64_t value) override;
void OnFrameEventReceived(const FrameCoordinationUnitImpl* frame_cu,
const mojom::Event event) override;
void OnPageEventReceived(const PageCoordinationUnitImpl* page_cu, void OnPageEventReceived(const PageCoordinationUnitImpl* page_cu,
const mojom::Event event) override; const mojom::Event event) override;
...@@ -71,6 +73,8 @@ class PageSignalGeneratorImpl : public CoordinationUnitGraphObserver, ...@@ -71,6 +73,8 @@ class PageSignalGeneratorImpl : public CoordinationUnitGraphObserver,
friend class PageSignalGeneratorImplTest; friend class PageSignalGeneratorImplTest;
FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest, IsLoading); FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest, IsLoading);
FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest, IsIdling); FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest, IsIdling);
FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest,
NonPersistentNotificationCreatedEvent);
FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest, FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest,
PageDataCorrectlyManaged); PageDataCorrectlyManaged);
FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest, FRIEND_TEST_ALL_PREFIXES(PageSignalGeneratorImplTest,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "services/resource_coordinator/observers/page_signal_generator_impl.h" #include "services/resource_coordinator/observers/page_signal_generator_impl.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h" #include "base/test/simple_test_tick_clock.h"
#include "services/resource_coordinator/coordination_unit/coordination_unit_test_harness.h" #include "services/resource_coordinator/coordination_unit/coordination_unit_test_harness.h"
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" #include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/resource_coordinator/resource_coordinator_clock.h" #include "services/resource_coordinator/resource_coordinator_clock.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace resource_coordinator { namespace resource_coordinator {
...@@ -34,6 +36,27 @@ class MockPageSignalGeneratorImpl : public PageSignalGeneratorImpl { ...@@ -34,6 +36,27 @@ class MockPageSignalGeneratorImpl : public PageSignalGeneratorImpl {
size_t eqt_change_count_ = 0; size_t eqt_change_count_ = 0;
}; };
class MockPageSignalReceiver : public mojom::PageSignalReceiver {
public:
MockPageSignalReceiver(mojom::PageSignalReceiverRequest request)
: binding_(this, std::move(request)) {}
~MockPageSignalReceiver() override = default;
// mojom::PageSignalReceiver implementation.
void NotifyPageAlmostIdle(const CoordinationUnitID& cu_id) override {}
void SetExpectedTaskQueueingDuration(const CoordinationUnitID& cu_id,
base::TimeDelta duration) override {}
void SetLifecycleState(const CoordinationUnitID& cu_id,
mojom::LifecycleState) override {}
MOCK_METHOD1(NotifyNonPersistentNotificationCreated,
void(const CoordinationUnitID& cu_id));
private:
mojo::Binding<mojom::PageSignalReceiver> binding_;
DISALLOW_COPY_AND_ASSIGN(MockPageSignalReceiver);
};
class PageSignalGeneratorImplTest : public CoordinationUnitTestHarness { class PageSignalGeneratorImplTest : public CoordinationUnitTestHarness {
protected: protected:
void TearDown() override { ResourceCoordinatorClock::ResetClockForTesting(); } void TearDown() override { ResourceCoordinatorClock::ResetClockForTesting(); }
...@@ -253,4 +276,27 @@ TEST_F(PageSignalGeneratorImplTest, PageAlmostIdleTransitionsWithTimeout) { ...@@ -253,4 +276,27 @@ TEST_F(PageSignalGeneratorImplTest, PageAlmostIdleTransitionsWithTimeout) {
TestPageAlmostIdleTransitions(true); TestPageAlmostIdleTransitions(true);
} }
TEST_F(PageSignalGeneratorImplTest, NonPersistentNotificationCreatedEvent) {
MockSinglePageInSingleProcessCoordinationUnitGraph cu_graph;
auto* frame_cu = cu_graph.frame.get();
// Create a mock receiver and register it against the psg.
mojom::PageSignalReceiverPtr mock_receiver_ptr;
MockPageSignalReceiver mock_receiver(mojo::MakeRequest(&mock_receiver_ptr));
page_signal_generator()->AddReceiver(std::move(mock_receiver_ptr));
base::RunLoop run_loop;
EXPECT_CALL(mock_receiver,
NotifyNonPersistentNotificationCreated(cu_graph.page->id()))
.WillOnce(::testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
// Send a mojom::Event::kNonPersistentNotificationCreated event and wait for
// the receiver to get it.
page_signal_generator()->OnFrameEventReceived(
frame_cu, mojom::Event::kNonPersistentNotificationCreated);
run_loop.Run();
::testing::Mock::VerifyAndClear(&mock_receiver);
}
} // namespace resource_coordinator } // namespace resource_coordinator
...@@ -20,6 +20,12 @@ interface PageSignalReceiver { ...@@ -20,6 +20,12 @@ interface PageSignalReceiver {
mojo_base.mojom.TimeDelta duration); mojo_base.mojom.TimeDelta duration);
SetLifecycleState(CoordinationUnitID cu_id, SetLifecycleState(CoordinationUnitID cu_id,
LifecycleState state); LifecycleState state);
// Indicates that the page has created a non-persistent web notification, i.e.
// a notification created by a particular page (in opposition to persistent
// web notifications, who require a service worker).
//
// |cu_id| is the coordination ID of the page that created this notification.
NotifyNonPersistentNotificationCreated(CoordinationUnitID cu_id);
}; };
// A PageSignalGenerator implementation will be implemented inside GRC to receive // A PageSignalGenerator implementation will be implemented inside GRC to receive
......
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