Commit 97e0114a authored by Michael Bai's avatar Michael Bai Committed by Tao Bai

ContentCapture: Remove the previous session upon the new one starts

- This will give the consumer the ability to discard the old content
ASAP.
- Also change the test to make it pass on BFCache feature.

Bug: 1115234
Change-Id: Ib41f5642018e6e11c919100b29bf7fb10e2f91b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2350126Reviewed-by: default avatarRakina Zata Amni <rakina@chromium.org>
Reviewed-by: default avatarChangwan Ryu <changwan@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798881}
parent 877eb8ee
......@@ -3,3 +3,9 @@ include_rules = [
"+content/public/test",
"+third_party/blink/public/common/associated_interfaces",
]
specific_include_rules = {
".*_test.cc": [
"+content/public/common",
],
}
......@@ -29,11 +29,7 @@ ContentCaptureReceiver::ContentCaptureReceiver(content::RenderFrameHost* rfh)
: rfh_(rfh), id_(GetIdFrom(rfh)) {}
ContentCaptureReceiver::~ContentCaptureReceiver() {
// TODO(crbug.com/995952): Find a way to notify of session being removed if
// rfh isn't available.
if (auto* manager = GetContentCaptureReceiverManager(rfh_)) {
manager->DidRemoveSession(this);
}
RemoveSession();
}
int64_t ContentCaptureReceiver::GetIdFrom(content::RenderFrameHost* rfh) {
......@@ -60,13 +56,14 @@ void ContentCaptureReceiver::DidCaptureContent(const ContentCaptureData& data,
// is changed, otherwise the child frame's session will be removed.
if (frame_content_capture_data_.id != 0 &&
frame_content_capture_data_.value != data.value) {
manager->DidRemoveSession(this);
RemoveSession();
}
frame_content_capture_data_.id = id_;
// Copies everything except id and children.
frame_content_capture_data_.value = data.value;
frame_content_capture_data_.bounds = data.bounds;
has_session_ = true;
}
// We can't avoid copy the data here, because id need to be overridden.
ContentCaptureData content(data);
......@@ -118,6 +115,21 @@ void ContentCaptureReceiver::StopCapture() {
}
}
void ContentCaptureReceiver::RemoveSession() {
if (!has_session_)
return;
// TODO(crbug.com/995952): Find a way to notify of session being removed if
// rfh isn't available.
if (auto* manager = GetContentCaptureReceiverManager(rfh_)) {
manager->DidRemoveSession(this);
has_session_ = false;
// We can reset the frame_content_capture_data_ here, because it could be
// used by GetFrameContentCaptureDataLastSeen(), has_session_ is used to
// check if new session shall be created as needed.
}
}
const mojo::AssociatedRemote<mojom::ContentCaptureSender>&
ContentCaptureReceiver::GetContentCaptureSender() {
if (!content_capture_sender_) {
......@@ -129,20 +141,19 @@ ContentCaptureReceiver::GetContentCaptureSender() {
const ContentCaptureData& ContentCaptureReceiver::GetFrameContentCaptureData() {
base::string16 url = base::UTF8ToUTF16(rfh_->GetLastCommittedURL().spec());
if (url == frame_content_capture_data_.value)
if (url == frame_content_capture_data_.value && has_session_)
return frame_content_capture_data_;
if (frame_content_capture_data_.id != 0) {
auto* manager = GetContentCaptureReceiverManager(rfh_);
DCHECK(manager);
manager->DidRemoveSession(this);
}
if (frame_content_capture_data_.id != 0 && has_session_)
RemoveSession();
frame_content_capture_data_.id = id_;
frame_content_capture_data_.value = url;
const base::Optional<gfx::Size>& size = rfh_->GetFrameSize();
if (size.has_value())
frame_content_capture_data_.bounds = gfx::Rect(size.value());
has_session_ = true;
return frame_content_capture_data_;
}
......
......@@ -50,6 +50,8 @@ class ContentCaptureReceiver : public mojom::ContentCaptureReceiver {
return frame_content_capture_data_;
}
void RemoveSession();
private:
FRIEND_TEST_ALL_PREFIXES(ContentCaptureReceiverTest, RenderFrameHostGone);
......@@ -68,6 +70,12 @@ class ContentCaptureReceiver : public mojom::ContentCaptureReceiver {
// ContentCaptureReceiverManager can't get parent frame id in both cases.
int64_t id_;
bool content_capture_enabled_ = false;
// Indicates whether this receiver is visible to consumer. It should be set
// upon the |frame_content_capture_data_| is created and reset on the session
// removed; the former is caused by either the content captured or the
// |frame_content_capture_data_| required by child frame.
bool has_session_ = false;
mojo::AssociatedRemote<mojom::ContentCaptureSender> content_capture_sender_;
DISALLOW_COPY_AND_ASSIGN(ContentCaptureReceiver);
};
......
......@@ -87,6 +87,16 @@ void ContentCaptureReceiverManager::RenderFrameDeleted(
void ContentCaptureReceiverManager::ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) {
// Don't remove the session for the same document navigation.
if (!navigation_handle->IsSameDocument()) {
if (auto* rfh = content::RenderFrameHost::FromID(
navigation_handle->GetPreviousRenderFrameHostId())) {
if (auto* receiver = ContentCaptureReceiverForFrame(rfh)) {
receiver->RemoveSession();
}
}
}
if (auto* receiver = ContentCaptureReceiverForFrame(
navigation_handle->GetRenderFrameHost())) {
if (web_contents()->GetBrowserContext()->IsOffTheRecord() ||
......
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