summaryrefslogtreecommitdiff
path: root/chromium/components/content_capture
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 11:40:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 12:42:11 +0000
commit5d87695f37678f96492b258bbab36486c59866b4 (patch)
treebe9783bbaf04fb930c4d74ca9c00b5e7954c8bc6 /chromium/components/content_capture
parent6c11fb357ec39bf087b8b632e2b1e375aef1b38b (diff)
downloadqtwebengine-chromium-5d87695f37678f96492b258bbab36486c59866b4.tar.gz
BASELINE: Update Chromium to 75.0.3770.56
Change-Id: I86d2007fd27a45d5797eee06f4c9369b8b50ac4f Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/content_capture')
-rw-r--r--chromium/components/content_capture/android/BUILD.gn5
-rw-r--r--chromium/components/content_capture/android/DEPS1
-rw-r--r--chromium/components/content_capture/android/content_capture_controller.cc96
-rw-r--r--chromium/components/content_capture/android/content_capture_controller.h49
-rw-r--r--chromium/components/content_capture/android/content_capture_receiver_manager_android.cc53
-rw-r--r--chromium/components/content_capture/android/content_capture_receiver_manager_android.h15
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java35
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureController.java58
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java8
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java23
-rw-r--r--chromium/components/content_capture/browser/DEPS1
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver.cc63
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver.h11
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver_manager.cc29
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver_manager.h6
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver_test.cc106
-rw-r--r--chromium/components/content_capture/common/content_capture.mojom9
-rw-r--r--chromium/components/content_capture/renderer/content_capture_sender.cc23
-rw-r--r--chromium/components/content_capture/renderer/content_capture_sender.h18
19 files changed, 540 insertions, 69 deletions
diff --git a/chromium/components/content_capture/android/BUILD.gn b/chromium/components/content_capture/android/BUILD.gn
index 7aeb2828c61..e231abd04a8 100644
--- a/chromium/components/content_capture/android/BUILD.gn
+++ b/chromium/components/content_capture/android/BUILD.gn
@@ -6,6 +6,8 @@ import("//build/config/android/rules.gni")
source_set("android") {
sources = [
+ "content_capture_controller.cc",
+ "content_capture_controller.h",
"content_capture_features_android.cc",
"content_capture_receiver_manager_android.cc",
"content_capture_receiver_manager_android.h",
@@ -13,6 +15,7 @@ source_set("android") {
deps = [
":jni_headers",
"//components/content_capture/browser",
+ "//third_party/re2",
]
}
@@ -23,6 +26,7 @@ android_library("java") {
]
java_files = [
"java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java",
+ "java/src/org/chromium/components/content_capture/ContentCaptureController.java",
"java/src/org/chromium/components/content_capture/ContentCaptureData.java",
"java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java",
"java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java",
@@ -32,6 +36,7 @@ android_library("java") {
generate_jni("jni_headers") {
sources = [
+ "java/src/org/chromium/components/content_capture/ContentCaptureController.java",
"java/src/org/chromium/components/content_capture/ContentCaptureData.java",
"java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java",
"java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java",
diff --git a/chromium/components/content_capture/android/DEPS b/chromium/components/content_capture/android/DEPS
index fb1ebefc6e4..e63745db9fd 100644
--- a/chromium/components/content_capture/android/DEPS
+++ b/chromium/components/content_capture/android/DEPS
@@ -2,4 +2,5 @@ include_rules = [
"+content/public/android",
"+content/public/browser",
"+jni",
+ "+third_party/re2",
] \ No newline at end of file
diff --git a/chromium/components/content_capture/android/content_capture_controller.cc b/chromium/components/content_capture/android/content_capture_controller.cc
new file mode 100644
index 00000000000..01c725a5d03
--- /dev/null
+++ b/chromium/components/content_capture/android/content_capture_controller.cc
@@ -0,0 +1,96 @@
+// Copyright 2019 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 "components/content_capture/android/content_capture_controller.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/no_destructor.h"
+#include "jni/ContentCaptureController_jni.h"
+#include "third_party/re2/src/re2/re2.h"
+
+using base::android::AppendJavaStringArrayToStringVector;
+using base::android::AttachCurrentThread;
+using base::android::JavaBooleanArrayToBoolVector;
+using base::android::JavaParamRef;
+using base::android::ScopedJavaLocalRef;
+
+namespace content_capture {
+
+// static
+jlong JNI_ContentCaptureController_Init(JNIEnv* env,
+ const JavaParamRef<jobject>& jcaller) {
+ auto* controller = ContentCaptureController::Get();
+ controller->SetJavaPeer(env, jcaller);
+ return reinterpret_cast<jlong>(controller);
+}
+
+// static
+ContentCaptureController* ContentCaptureController::Get() {
+ static base::NoDestructor<ContentCaptureController> s;
+ return s.get();
+}
+
+ContentCaptureController::ContentCaptureController() = default;
+ContentCaptureController::~ContentCaptureController() = default;
+
+void ContentCaptureController::SetWhitelist(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jcaller,
+ const JavaParamRef<jobjectArray>& jwhitelist,
+ const JavaParamRef<jbooleanArray>& jisRegEx) {
+ DCHECK(jwhitelist && jisRegEx || !(jwhitelist || jisRegEx));
+ has_whitelist_ = false;
+ if (!jwhitelist)
+ return;
+ std::vector<std::string> whitelist;
+ std::vector<bool> is_regex;
+ AppendJavaStringArrayToStringVector(env, jwhitelist, &whitelist);
+ JavaBooleanArrayToBoolVector(env, jisRegEx, &is_regex);
+ if (whitelist.size() != is_regex.size())
+ return;
+ has_whitelist_ = true;
+ size_t index = 0;
+ for (auto w : whitelist) {
+ if (is_regex[index++])
+ whitelist_regex_.push_back(std::make_unique<re2::RE2>(w));
+ else
+ whitelist_.push_back(w);
+ }
+}
+
+void ContentCaptureController::SetJavaPeer(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jcaller) {
+ java_ref_ = JavaObjectWeakGlobalRef(env, jcaller);
+}
+
+bool ContentCaptureController::ShouldCapture(const GURL& url) {
+ if (!has_whitelist_.has_value()) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return false;
+ Java_ContentCaptureController_pullWhitelist(env, obj);
+ }
+ DCHECK(has_whitelist_.has_value());
+
+ // Everything is whitelisted.
+ if (!has_whitelist_.value() || !url.has_host())
+ return true;
+
+ std::string host = url.host();
+ for (auto& w : whitelist_) {
+ if (w == host)
+ return true;
+ }
+
+ for (auto& w : whitelist_regex_) {
+ if (re2::RE2::FullMatch(host, *w))
+ return true;
+ }
+ return false;
+}
+
+} // namespace content_capture
diff --git a/chromium/components/content_capture/android/content_capture_controller.h b/chromium/components/content_capture/android/content_capture_controller.h
new file mode 100644
index 00000000000..57b50bf8130
--- /dev/null
+++ b/chromium/components/content_capture/android/content_capture_controller.h
@@ -0,0 +1,49 @@
+// Copyright 2019 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 COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_CONTROLLER_H_
+#define COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_CONTROLLER_H_
+
+#include "base/android/jni_weak_ref.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/optional.h"
+#include "url/gurl.h"
+
+namespace re2 {
+class RE2;
+} // namespace re2
+
+namespace content_capture {
+
+// This class has one instance per process and is called by
+// ContentReceiverManager to check if the given url shall be captured.
+class ContentCaptureController {
+ public:
+ static ContentCaptureController* Get();
+
+ // Not call constructor directly, instead, uses Get().
+ ContentCaptureController();
+
+ // Returns if the given |url| shall be captured.
+ bool ShouldCapture(const GURL& url);
+
+ // The methods called by Java peer.
+ void SetWhitelist(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jcaller,
+ const base::android::JavaParamRef<jobjectArray>& jwhitelist,
+ const base::android::JavaParamRef<jbooleanArray>& jtype);
+ void SetJavaPeer(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jcaller);
+
+ private:
+ virtual ~ContentCaptureController();
+ JavaObjectWeakGlobalRef java_ref_;
+ base::Optional<bool> has_whitelist_;
+ std::vector<std::string> whitelist_;
+ std::vector<std::unique_ptr<re2::RE2>> whitelist_regex_;
+};
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_CONTROLLER_H_
diff --git a/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc b/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc
index 522bfdef526..e514dc34618 100644
--- a/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc
+++ b/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc
@@ -9,6 +9,7 @@
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
+#include "components/content_capture/android/content_capture_controller.h"
#include "content/public/browser/web_contents.h"
#include "jni/ContentCaptureData_jni.h"
#include "jni/ContentCaptureReceiverManager_jni.h"
@@ -19,16 +20,22 @@ using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
using base::android::ToJavaLongArray;
-void JNI_ContentCaptureReceiverManager_Init(
+static ScopedJavaLocalRef<jobject>
+JNI_ContentCaptureReceiverManager_CreateOrGet(
JNIEnv* env,
- const base::android::JavaParamRef<jobject>& jcaller,
- const base::android::JavaParamRef<jobject>& jweb_contents) {
- auto* web_contents = content::WebContents::FromJavaWebContents(jweb_contents);
+ const base::android::JavaParamRef<jobject>& jwebContents) {
+ auto* web_contents = content::WebContents::FromJavaWebContents(jwebContents);
DCHECK(web_contents);
- DCHECK(!content_capture::ContentCaptureReceiverManager::FromWebContents(
- web_contents));
- content_capture::ContentCaptureReceiverManagerAndroid::Create(web_contents,
- jcaller);
+ auto* manager =
+ content_capture::ContentCaptureReceiverManager::FromWebContents(
+ web_contents);
+ if (!manager) {
+ manager = content_capture::ContentCaptureReceiverManagerAndroid::Create(
+ env, web_contents);
+ }
+ return static_cast<content_capture::ContentCaptureReceiverManagerAndroid*>(
+ manager)
+ ->GetJavaObject();
}
namespace content_capture {
@@ -73,19 +80,22 @@ ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfContentCaptureData(
} // namespace
ContentCaptureReceiverManagerAndroid::ContentCaptureReceiverManagerAndroid(
- content::WebContents* web_contents,
- const JavaRef<jobject>& jcaller)
- : ContentCaptureReceiverManager(web_contents), java_ref_(jcaller) {}
+ JNIEnv* env,
+ content::WebContents* web_contents)
+ : ContentCaptureReceiverManager(web_contents),
+ java_ref_(Java_ContentCaptureReceiverManager_Constructor(env)) {}
ContentCaptureReceiverManagerAndroid::~ContentCaptureReceiverManagerAndroid() =
default;
-void ContentCaptureReceiverManagerAndroid::Create(
- content::WebContents* web_contents,
- const JavaRef<jobject>& jcaller) {
- if (FromWebContents(web_contents))
- return;
- new ContentCaptureReceiverManagerAndroid(web_contents, jcaller);
+ContentCaptureReceiverManagerAndroid*
+ContentCaptureReceiverManagerAndroid::Create(
+ JNIEnv* env,
+ content::WebContents* web_contents) {
+ auto* manager = FromWebContents(web_contents);
+ if (manager)
+ return static_cast<ContentCaptureReceiverManagerAndroid*>(manager);
+ return new ContentCaptureReceiverManagerAndroid(env, web_contents);
}
void ContentCaptureReceiverManagerAndroid::DidCaptureContent(
@@ -121,4 +131,13 @@ void ContentCaptureReceiverManagerAndroid::DidRemoveSession(
env, java_ref_, ToJavaArrayOfContentCaptureData(env, session));
}
+bool ContentCaptureReceiverManagerAndroid::ShouldCapture(const GURL& url) {
+ return ContentCaptureController::Get()->ShouldCapture(url);
+}
+
+ScopedJavaLocalRef<jobject>
+ContentCaptureReceiverManagerAndroid::GetJavaObject() {
+ return ScopedJavaLocalRef<jobject>(java_ref_);
+}
+
} // namespace content_capture
diff --git a/chromium/components/content_capture/android/content_capture_receiver_manager_android.h b/chromium/components/content_capture/android/content_capture_receiver_manager_android.h
index 46ec64df0b6..12a9b321703 100644
--- a/chromium/components/content_capture/android/content_capture_receiver_manager_android.h
+++ b/chromium/components/content_capture/android/content_capture_receiver_manager_android.h
@@ -18,8 +18,9 @@ class ContentCaptureReceiverManagerAndroid
: public ContentCaptureReceiverManager {
public:
~ContentCaptureReceiverManagerAndroid() override;
- static void Create(content::WebContents* web_contents,
- const base::android::JavaRef<jobject>& jcaller);
+ static ContentCaptureReceiverManagerAndroid* Create(
+ JNIEnv* env,
+ content::WebContents* web_contents);
void DidCaptureContent(const ContentCaptureSession& parent_session,
const ContentCaptureData& data) override;
@@ -27,10 +28,14 @@ class ContentCaptureReceiverManagerAndroid
const std::vector<int64_t>& data) override;
void DidRemoveSession(const ContentCaptureSession& session) override;
+ base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
+
+ protected:
+ bool ShouldCapture(const GURL& url) override;
+
private:
- ContentCaptureReceiverManagerAndroid(
- content::WebContents* web_contents,
- const base::android::JavaRef<jobject>& jcaller);
+ ContentCaptureReceiverManagerAndroid(JNIEnv* env,
+ content::WebContents* web_contents);
base::android::ScopedJavaGlobalRef<jobject> java_ref_;
};
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
index d9a458dbb12..aacf65df9e6 100644
--- a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
@@ -4,27 +4,52 @@
package org.chromium.components.content_capture;
+import org.chromium.content_public.browser.WebContents;
+
/**
- * This interface is for consumer to consume the captured content.
+ * This abstract class is for consumer to consume the captured content.
*/
-public interface ContentCaptureConsumer {
+public abstract class ContentCaptureConsumer {
+ private ContentCaptureReceiverManager mManager;
+ public ContentCaptureConsumer(WebContents webContents) {
+ onWebContentsChanged(webContents);
+ }
+
/**
* Invoked when the content is captured from a frame.
* @param parentFrame is the parent of the frame from that the content captured.
* @param contentCaptureData is the captured content tree, its root is the frame.
*/
- void onContentCaptured(FrameSession parentFrame, ContentCaptureData contentCaptureData);
+ public abstract void onContentCaptured(
+ FrameSession parentFrame, ContentCaptureData contentCaptureData);
/**
* Invoked when the session is removed
* @param session is the removed frame.
*/
- void onSessionRemoved(FrameSession session);
+ public abstract void onSessionRemoved(FrameSession session);
/**
* Invoked when the content is removed from a frame
* @param session defines the frame from that the content removed
* @param removedIds are array of removed content id.
*/
- void onContentRemoved(FrameSession session, long[] removedIds);
+ public abstract void onContentRemoved(FrameSession session, long[] removedIds);
+
+ public void onWebContentsChanged(WebContents current) {
+ if (!ContentCaptureFeatures.isEnabled()) return;
+ if (mManager != null) mManager.setContentCaptureConsumer(null);
+ if (current != null) {
+ mManager = ContentCaptureReceiverManager.createOrGet(current);
+ mManager.setContentCaptureConsumer(this);
+ } else {
+ mManager = null;
+ }
+ }
+
+ public void destroy() {
+ if (mManager == null) return;
+ mManager.setContentCaptureConsumer(null);
+ mManager = null;
+ }
}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureController.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureController.java
new file mode 100644
index 00000000000..8de95c970e0
--- /dev/null
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureController.java
@@ -0,0 +1,58 @@
+// Copyright 2019 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.
+
+package org.chromium.components.content_capture;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * The abstract class to provide the whitelist and the runtime control of if ContentCapture should
+ * start.
+ */
+@JNINamespace("content_capture")
+public abstract class ContentCaptureController {
+ /**
+ * The singleton instance of ContentCaptureController, shall be set by subclass.
+ */
+ protected static ContentCaptureController sContentCaptureController;
+
+ private long mNativeContentCaptureController;
+
+ public static ContentCaptureController getInstance() {
+ return sContentCaptureController;
+ }
+
+ protected ContentCaptureController() {
+ mNativeContentCaptureController = nativeInit(this);
+ }
+
+ /**
+ * @return if ContentCapture should be started for this app at all.
+ */
+ public abstract boolean shouldStartCapture();
+
+ /**
+ * Invoked by native side to pull the whitelist, the subclass should implement this and set
+ * the whitelist by call setWhiteList.
+ */
+ @CalledByNative
+ protected abstract void pullWhitelist();
+
+ /**
+ * Invoked by subclass to set the whitelist to native side. No whitelist (whitelist == null)
+ * indicates everything is whitelisted, empty whitelist (whitelist.length == 0) indicates
+ * nothing is whitelisted.
+ *
+ * @param whitelist the array of whitelist, it could be the hostname or the regex.
+ * @param isRegex to indicate that the corresponding whitelist is the regex or not.
+ */
+ protected void setWhitelist(String[] whitelist, boolean[] isRegex) {
+ nativeSetWhitelist(mNativeContentCaptureController, whitelist, isRegex);
+ }
+
+ private static native long nativeInit(Object contentCaptureController);
+ private native void nativeSetWhitelist(
+ long nativeContentCaptureController, String[] whitelist, boolean[] isRegex);
+}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java
index dc7ad565197..7400008628f 100644
--- a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java
@@ -3,12 +3,20 @@
// found in the LICENSE file.
package org.chromium.components.content_capture;
+import org.chromium.base.CommandLine;
+
/**
* The class to get if feature is enabled from native.
*/
public class ContentCaptureFeatures {
+ private static final String FLAG = "dump-captured-content-to-logcat-for-testing";
+
public static boolean isEnabled() {
return nativeIsEnabled();
}
+
+ public static boolean isDumpForTestingEnabled() {
+ return CommandLine.getInstance().hasSwitch(FLAG);
+ }
private static native boolean nativeIsEnabled();
}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
index c217f21c317..f6d7e8f6c0a 100644
--- a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
@@ -4,9 +4,6 @@
package org.chromium.components.content_capture;
-import android.view.ViewGroup;
-
-import org.chromium.base.CommandLine;
import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.content_public.browser.WebContents;
@@ -18,25 +15,17 @@ import java.util.Arrays;
*/
public class ContentCaptureReceiverManager {
private static final String TAG = "ContentCapture";
- private static final String FLAG = "dump-captured-content-to-logcat-for-testing";
private static Boolean sDump;
private ContentCaptureConsumer mContentCaptureConsumer;
- public static ContentCaptureReceiverManager create(WebContents webContents) {
- ContentCaptureReceiverManager manager = new ContentCaptureReceiverManager();
- manager.nativeInit(webContents);
- return manager;
- }
-
- public ContentCaptureReceiverManager() {
- if (sDump == null) sDump = CommandLine.getInstance().hasSwitch(FLAG);
+ public static ContentCaptureReceiverManager createOrGet(WebContents webContents) {
+ return nativeCreateOrGet(webContents);
}
- public void onContainerViewChanged(ViewGroup containerView) {
- // Reset current consumer, the new consumer that associates with contanerView shall be set
- // from setContentCaptureConsumer().
- mContentCaptureConsumer = null;
+ @CalledByNative
+ private ContentCaptureReceiverManager() {
+ if (sDump == null) sDump = ContentCaptureFeatures.isDumpForTestingEnabled();
}
public void setContentCaptureConsumer(ContentCaptureConsumer consumer) {
@@ -74,5 +63,5 @@ public class ContentCaptureReceiverManager {
return frameSession;
}
- private native void nativeInit(WebContents webContents);
+ private static native ContentCaptureReceiverManager nativeCreateOrGet(WebContents webContents);
}
diff --git a/chromium/components/content_capture/browser/DEPS b/chromium/components/content_capture/browser/DEPS
index d79a7d00f02..8d9595f2bfb 100644
--- a/chromium/components/content_capture/browser/DEPS
+++ b/chromium/components/content_capture/browser/DEPS
@@ -1,4 +1,5 @@
include_rules = [
"+content/public/browser",
"+content/public/test",
+ "+third_party/blink/public/common/associated_interfaces",
]
diff --git a/chromium/components/content_capture/browser/content_capture_receiver.cc b/chromium/components/content_capture/browser/content_capture_receiver.cc
index 394869bd014..b0573e9500a 100644
--- a/chromium/components/content_capture/browser/content_capture_receiver.cc
+++ b/chromium/components/content_capture/browser/content_capture_receiver.cc
@@ -6,9 +6,11 @@
#include <utility>
+#include "base/strings/utf_string_conversions.h"
#include "components/content_capture/browser/content_capture_receiver_manager.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
namespace content_capture {
@@ -35,8 +37,12 @@ void ContentCaptureReceiver::DidCaptureContent(const ContentCaptureData& data,
if (first_data) {
// The session id of this frame isn't changed for new document navigation,
// so the previous session should be terminated.
- if (frame_content_capture_data_.id != 0)
+ // The parent frame might be captured after child, we need to check if url
+ // 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);
+ }
frame_content_capture_data_.id = id_;
// Copies everything except id and children.
@@ -46,6 +52,10 @@ void ContentCaptureReceiver::DidCaptureContent(const ContentCaptureData& data,
// We can't avoid copy the data here, because id need to be overriden.
ContentCaptureData content(data);
content.id = id_;
+ // Always have frame URL attached, since the ContentCaptureConsumer will
+ // be reset once activity is resumed, URL is needed to rebuild session.
+ if (!first_data)
+ content.value = frame_content_capture_data_.value;
manager->DidCaptureContent(this, content);
}
@@ -56,4 +66,55 @@ void ContentCaptureReceiver::DidRemoveContent(
manager->DidRemoveContent(this, data);
}
+void ContentCaptureReceiver::StartCapture() {
+ if (content_capture_enabled)
+ return;
+
+ if (auto& sender = GetContentCaptureSender()) {
+ sender->StartCapture();
+ content_capture_enabled = true;
+ }
+}
+
+void ContentCaptureReceiver::StopCapture() {
+ if (!content_capture_enabled)
+ return;
+
+ if (auto& sender = GetContentCaptureSender()) {
+ sender->StopCapture();
+ content_capture_enabled = false;
+ }
+}
+
+const mojom::ContentCaptureSenderAssociatedPtr&
+ContentCaptureReceiver::GetContentCaptureSender() {
+ if (!content_capture_sender_) {
+ rfh_->GetRemoteAssociatedInterfaces()->GetInterface(
+ mojo::MakeRequest(&content_capture_sender_));
+ }
+ return content_capture_sender_;
+}
+
+const ContentCaptureData& ContentCaptureReceiver::GetFrameContentCaptureData() {
+ base::string16 url = base::UTF8ToUTF16(rfh_->GetLastCommittedURL().spec());
+ if (url == frame_content_capture_data_.value)
+ return frame_content_capture_data_;
+
+ bool should_remove_session = frame_content_capture_data_.id != 0;
+ 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());
+
+ // frame_content_capture_data_ must be set to new value before removing
+ // sesesion, otherwises, it causes infinite loop.
+ if (should_remove_session) {
+ auto* manager = ContentCaptureReceiverManager::FromWebContents(
+ content::WebContents::FromRenderFrameHost(rfh_));
+ manager->DidRemoveSession(this);
+ }
+ return frame_content_capture_data_;
+}
+
} // namespace content_capture
diff --git a/chromium/components/content_capture/browser/content_capture_receiver.h b/chromium/components/content_capture/browser/content_capture_receiver.h
index d745b072423..f3a6522ac9a 100644
--- a/chromium/components/content_capture/browser/content_capture_receiver.h
+++ b/chromium/components/content_capture/browser/content_capture_receiver.h
@@ -33,15 +33,17 @@ class ContentCaptureReceiver : public mojom::ContentCaptureReceiver {
void DidCaptureContent(const ContentCaptureData& data,
bool first_data) override;
void DidRemoveContent(const std::vector<int64_t>& data) override;
+ void StartCapture();
+ void StopCapture();
content::RenderFrameHost* rfh() const { return rfh_; }
// Return ContentCaptureData of the associated frame.
- const ContentCaptureData& frame_content_capture_data() const {
- return frame_content_capture_data_;
- }
+ const ContentCaptureData& GetFrameContentCaptureData();
private:
+ const mojom::ContentCaptureSenderAssociatedPtr& GetContentCaptureSender();
+
mojo::AssociatedBinding<mojom::ContentCaptureReceiver> bindings_;
content::RenderFrameHost* rfh_;
ContentCaptureData frame_content_capture_data_;
@@ -53,7 +55,8 @@ class ContentCaptureReceiver : public mojom::ContentCaptureReceiver {
// frame's; if the Id is generated in sender, the
// ContentCaptureReceiverManager can't get parent frame id in both cases.
int64_t id_;
-
+ bool content_capture_enabled = false;
+ mojom::ContentCaptureSenderAssociatedPtr content_capture_sender_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ContentCaptureReceiver);
};
diff --git a/chromium/components/content_capture/browser/content_capture_receiver_manager.cc b/chromium/components/content_capture/browser/content_capture_receiver_manager.cc
index 57e7702c39d..353ef88bd78 100644
--- a/chromium/components/content_capture/browser/content_capture_receiver_manager.cc
+++ b/chromium/components/content_capture/browser/content_capture_receiver_manager.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "components/content_capture/browser/content_capture_receiver.h"
+#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
namespace content_capture {
@@ -30,12 +31,14 @@ ContentCaptureReceiverManager::ContentCaptureReceiverManager(
ContentCaptureReceiverManager::~ContentCaptureReceiverManager() = default;
+// static
ContentCaptureReceiverManager* ContentCaptureReceiverManager::FromWebContents(
content::WebContents* contents) {
return static_cast<ContentCaptureReceiverManager*>(
contents->GetUserData(kUserDataKey));
}
+// static
void ContentCaptureReceiverManager::BindContentCaptureReceiver(
mojom::ContentCaptureReceiverAssociatedRequest request,
content::RenderFrameHost* render_frame_host) {
@@ -79,13 +82,23 @@ void ContentCaptureReceiverManager::RenderFrameDeleted(
frame_map_.erase(render_frame_host);
}
+void ContentCaptureReceiverManager::ReadyToCommitNavigation(
+ content::NavigationHandle* navigation_handle) {
+ auto* receiver =
+ ContentCaptureReceiverForFrame(navigation_handle->GetRenderFrameHost());
+ if (ShouldCapture(navigation_handle->GetURL()))
+ receiver->StartCapture();
+ else
+ receiver->StopCapture();
+}
+
void ContentCaptureReceiverManager::DidCaptureContent(
ContentCaptureReceiver* content_capture_receiver,
const ContentCaptureData& data) {
// The root of |data| is frame, we need get its ancestor only.
ContentCaptureSession parent_session;
- BuildContentCaptureSession(*content_capture_receiver,
- true /* ancestor_only */, &parent_session);
+ BuildContentCaptureSession(content_capture_receiver, true /* ancestor_only */,
+ &parent_session);
DidCaptureContent(parent_session, data);
}
@@ -95,7 +108,7 @@ void ContentCaptureReceiverManager::DidRemoveContent(
ContentCaptureSession session;
// The |data| is a list of text content id, the session should include
// |content_capture_receiver| associated frame.
- BuildContentCaptureSession(*content_capture_receiver,
+ BuildContentCaptureSession(content_capture_receiver,
false /* ancestor_only */, &session);
DidRemoveContent(session, data);
}
@@ -105,19 +118,19 @@ void ContentCaptureReceiverManager::DidRemoveSession(
ContentCaptureSession session;
// The session should include the removed frame that the
// |content_capture_receiver| associated with.
- BuildContentCaptureSession(*content_capture_receiver,
+ BuildContentCaptureSession(content_capture_receiver,
false /* ancestor_only */, &session);
DidRemoveSession(session);
}
void ContentCaptureReceiverManager::BuildContentCaptureSession(
- const ContentCaptureReceiver& content_capture_receiver,
+ ContentCaptureReceiver* content_capture_receiver,
bool ancestor_only,
ContentCaptureSession* session) {
if (!ancestor_only)
- session->push_back(content_capture_receiver.frame_content_capture_data());
+ session->push_back(content_capture_receiver->GetFrameContentCaptureData());
- content::RenderFrameHost* rfh = content_capture_receiver.rfh()->GetParent();
+ content::RenderFrameHost* rfh = content_capture_receiver->rfh()->GetParent();
while (rfh) {
ContentCaptureReceiver* receiver = ContentCaptureReceiverForFrame(rfh);
// TODO(michaelbai): Only creates ContentCaptureReceiver here, clean up the
@@ -126,7 +139,7 @@ void ContentCaptureReceiverManager::BuildContentCaptureSession(
RenderFrameCreated(rfh);
receiver = ContentCaptureReceiverForFrame(rfh);
}
- session->push_back(receiver->frame_content_capture_data());
+ session->push_back(receiver->GetFrameContentCaptureData());
rfh = receiver->rfh()->GetParent();
}
}
diff --git a/chromium/components/content_capture/browser/content_capture_receiver_manager.h b/chromium/components/content_capture/browser/content_capture_receiver_manager.h
index 4ddbc8b1d80..2e16c4da0cc 100644
--- a/chromium/components/content_capture/browser/content_capture_receiver_manager.h
+++ b/chromium/components/content_capture/browser/content_capture_receiver_manager.h
@@ -50,6 +50,8 @@ class ContentCaptureReceiverManager : public content::WebContentsObserver,
// content::WebContentsObserver:
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
+ void ReadyToCommitNavigation(
+ content::NavigationHandle* navigation_handle) override;
size_t GetFrameMapSizeForTesting() const { return frame_map_.size(); }
@@ -66,13 +68,15 @@ class ContentCaptureReceiverManager : public content::WebContentsObserver,
// Invoked when the given |session| was removed.
virtual void DidRemoveSession(const ContentCaptureSession& session) = 0;
+ virtual bool ShouldCapture(const GURL& url) = 0;
+
private:
friend class ContentCaptureReceiverManagerHelper;
// Builds ContentCaptureSession and returns in |session|, |ancestor_only|
// specifies if only ancestor should be returned in |session|.
void BuildContentCaptureSession(
- const ContentCaptureReceiver& content_capture_receiver,
+ ContentCaptureReceiver* content_capture_receiver,
bool ancestor_only,
ContentCaptureSession* session);
diff --git a/chromium/components/content_capture/browser/content_capture_receiver_test.cc b/chromium/components/content_capture/browser/content_capture_receiver_test.cc
index 9ada1eb1209..7c411e0795b 100644
--- a/chromium/components/content_capture/browser/content_capture_receiver_test.cc
+++ b/chromium/components/content_capture/browser/content_capture_receiver_test.cc
@@ -18,6 +18,10 @@
namespace content_capture {
namespace {
+static const char kMainFrameUrl[] = "http://foo.com/main.html";
+static const char kMainFrameUrl2[] = "http://foo.com/2.html";
+static const char kChildFrameUrl[] = "http://foo.org/child.html";
+
// Fake ContentCaptureSender to call ContentCaptureReceiver mojom interface.
class FakeContentCaptureSender {
public:
@@ -70,6 +74,8 @@ class ContentCaptureReceiverManagerHelper
removed_session_ = data;
}
+ bool ShouldCapture(const GURL& url) override { return false; }
+
const ContentCaptureSession& parent_session() const {
return parent_session_;
}
@@ -102,7 +108,7 @@ class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
ContentCaptureReceiverManager::FromWebContents(web_contents()));
// This needed to keep the WebContentsObserverSanityChecker checks happy for
// when AppendChild is called.
- NavigateAndCommit(GURL("about:blank"));
+ NavigateAndCommit(GURL(kMainFrameUrl));
content_capture_sender_ = std::make_unique<FakeContentCaptureSender>();
main_frame_ = web_contents()->GetMainFrame();
// Binds sender with receiver.
@@ -115,12 +121,26 @@ class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
child.value = base::ASCIIToUTF16("Hello");
child.bounds = gfx::Rect(5, 5, 5, 5);
// No need to set id in sender.
- test_data_.value = base::ASCIIToUTF16("http://foo.com/bar");
+ test_data_.value = base::ASCIIToUTF16(kMainFrameUrl);
test_data_.bounds = gfx::Rect(10, 10);
test_data_.children.push_back(child);
- test_data2_.value = base::ASCIIToUTF16("http://foo.org/bar");
+ test_data2_.value = base::ASCIIToUTF16(kChildFrameUrl);
test_data2_.bounds = gfx::Rect(10, 10);
test_data2_.children.push_back(child);
+ // Update to test_data_.
+ ContentCaptureData child2;
+ // Have the unique id for text content.
+ child2.id = 3;
+ child2.value = base::ASCIIToUTF16("World");
+ child2.bounds = gfx::Rect(5, 10, 5, 5);
+ test_data_update_.value = base::ASCIIToUTF16(kMainFrameUrl);
+ test_data_update_.bounds = gfx::Rect(10, 10);
+ test_data_update_.children.push_back(child2);
+ }
+
+ void NavigateMainFrame(const GURL& url) {
+ NavigateAndCommit(url);
+ main_frame_ = web_contents()->GetMainFrame();
}
void SetupChildFrame() {
@@ -143,6 +163,9 @@ class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
const ContentCaptureData& test_data() const { return test_data_; }
const ContentCaptureData& test_data2() const { return test_data2_; }
+ const ContentCaptureData& test_data_update() const {
+ return test_data_update_;
+ }
const std::vector<int64_t>& expected_removed_ids() const {
return expected_removed_ids_;
}
@@ -163,6 +186,14 @@ class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
return expected;
}
+ ContentCaptureData GetExpectedTestDataUpdate(bool main_frame) const {
+ ContentCaptureData expected(test_data_update_);
+ // Replaces the id with expected id.
+ expected.id = ContentCaptureReceiver::GetIdFrom(main_frame ? main_frame_
+ : child_frame_);
+ return expected;
+ }
+
ContentCaptureReceiverManagerHelper* content_capture_receiver_manager_helper()
const {
return content_capture_receiver_manager_helper_;
@@ -175,6 +206,7 @@ class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
EXPECT_EQ(expected[i].id, result[i].id);
EXPECT_EQ(expected[i].value, result[i].value);
EXPECT_EQ(expected[i].bounds, result[i].bounds);
+ EXPECT_TRUE(result[i].children.empty());
}
}
@@ -213,6 +245,7 @@ class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
content::RenderFrameHost* child_frame_ = nullptr;
ContentCaptureData test_data_;
ContentCaptureData test_data2_;
+ ContentCaptureData test_data_update_;
// Expected removed Ids.
std::vector<int64_t> expected_removed_ids_{2};
};
@@ -237,14 +270,14 @@ TEST_F(ContentCaptureReceiverTest, DidCaptureContentWithUpdate) {
EXPECT_EQ(GetExpectedTestData(true /* main_frame */),
content_capture_receiver_manager_helper()->captured_data());
// Simulates to update the content within the same document.
- DidCaptureContent(test_data2(), false /* first_data */);
+ DidCaptureContent(test_data_update(), false /* first_data */);
// Verifies to get test_data2() with correct frame content id.
EXPECT_TRUE(
content_capture_receiver_manager_helper()->parent_session().empty());
// Verifies that the sesssion isn't removed.
EXPECT_TRUE(
content_capture_receiver_manager_helper()->removed_session().empty());
- EXPECT_EQ(GetExpectedTestData2(true /* main_frame */),
+ EXPECT_EQ(GetExpectedTestDataUpdate(true /* main_frame */),
content_capture_receiver_manager_helper()->captured_data());
}
@@ -324,6 +357,69 @@ TEST_F(ContentCaptureReceiverTest, ChildFrameDidCaptureContent) {
content_capture_receiver_manager_helper()->captured_data());
}
+TEST_F(ContentCaptureReceiverTest, ChildFrameCaptureContentFirst) {
+ // Simulate add child frame.
+ SetupChildFrame();
+ // Simulate to capture the content from child frame.
+ DidCaptureContentForChildFrame(test_data2(), true /* first_data */);
+ // Verifies that the parent_session was set correctly.
+ EXPECT_FALSE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+
+ ContentCaptureData data = GetExpectedTestData(true /* main_frame */);
+ // Currently, there is no way to fake frame size, set it to 0.
+ data.bounds = gfx::Rect();
+ std::vector<ContentCaptureData> expected{data};
+
+ VerifySession(expected,
+ content_capture_receiver_manager_helper()->parent_session());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ // Verifies that we receive the correct content from child frame.
+ EXPECT_EQ(GetExpectedTestData2(false /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+
+ // When main frame navigates to same url, the parent session will not change.
+ NavigateMainFrame(GURL(kMainFrameUrl));
+ SetupChildFrame();
+ DidCaptureContentForChildFrame(test_data2(), true /* first_data */);
+ VerifySession(expected,
+ content_capture_receiver_manager_helper()->parent_session());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+
+ // When main frame navigates to same domain, the parent session will change.
+ NavigateMainFrame(GURL(kMainFrameUrl2));
+ SetupChildFrame();
+ DidCaptureContentForChildFrame(test_data2(), true /* first_data */);
+
+ // Intentionally reuse the data.id from previous result, so we know navigating
+ // to same domain didn't create new ContentCaptureReceiver when call
+ // VerifySession(), otherwise, we can't test the code to handle the navigation
+ // in ContentCaptureReceiver.
+ data.value = base::ASCIIToUTF16(kMainFrameUrl2);
+ // Currently, there is no way to fake frame size, set it to 0.
+ data.bounds = gfx::Rect();
+ expected.clear();
+ expected.push_back(data);
+ VerifySession(expected,
+ content_capture_receiver_manager_helper()->parent_session());
+
+ // When main frame navigates to different domain, the parent session will
+ // change.
+ NavigateMainFrame(GURL(kChildFrameUrl));
+ SetupChildFrame();
+ DidCaptureContentForChildFrame(test_data2(), true /* first_data */);
+
+ data = GetExpectedTestData2(true /* main_frame */);
+ // Currently, there is no way to fake frame size, set it to 0.
+ data.bounds = gfx::Rect();
+ expected.clear();
+ expected.push_back(data);
+ VerifySession(expected,
+ content_capture_receiver_manager_helper()->parent_session());
+}
+
class ContentCaptureReceiverMultipleFrameTest
: public ContentCaptureReceiverTest {
public:
diff --git a/chromium/components/content_capture/common/content_capture.mojom b/chromium/components/content_capture/common/content_capture.mojom
index 5bb2ff35dc1..a6591428e94 100644
--- a/chromium/components/content_capture/common/content_capture.mojom
+++ b/chromium/components/content_capture/common/content_capture.mojom
@@ -15,4 +15,11 @@ interface ContentCaptureReceiver {
// Invoked to notify that a list of content |ids| has been removed.
DidRemoveContent(array<int64> ids);
-}; \ No newline at end of file
+};
+
+// This interface has one instance per RenderFrame in renderer process.
+interface ContentCaptureSender {
+ // Invoked to start/stop ContentCapture, it is stopped by default.
+ StartCapture();
+ StopCapture();
+};
diff --git a/chromium/components/content_capture/renderer/content_capture_sender.cc b/chromium/components/content_capture/renderer/content_capture_sender.cc
index 989ec63b723..e3730c7533d 100644
--- a/chromium/components/content_capture/renderer/content_capture_sender.cc
+++ b/chromium/components/content_capture/renderer/content_capture_sender.cc
@@ -9,19 +9,28 @@
#include "components/content_capture/common/content_capture_features.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/web/web_content_holder.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
namespace content_capture {
-ContentCaptureSender::ContentCaptureSender(content::RenderFrame* render_frame)
- : content::RenderFrameObserver(render_frame) {
- render_frame->GetWebFrame()->SetContentCaptureClient(this);
+ContentCaptureSender::ContentCaptureSender(
+ content::RenderFrame* render_frame,
+ blink::AssociatedInterfaceRegistry* registry)
+ : content::RenderFrameObserver(render_frame), binding_(this) {
+ registry->AddInterface(base::BindRepeating(&ContentCaptureSender::BindRequest,
+ base::Unretained(this)));
}
ContentCaptureSender::~ContentCaptureSender() {}
+void ContentCaptureSender::BindRequest(
+ mojom::ContentCaptureSenderAssociatedRequest request) {
+ binding_.Bind(std::move(request));
+}
+
cc::NodeHolder::Type ContentCaptureSender::GetNodeHolderType() const {
if (content_capture::features::ShouldUseNodeID())
return cc::NodeHolder::Type::kID;
@@ -64,6 +73,14 @@ void ContentCaptureSender::DidRemoveContent(const std::vector<int64_t>& data) {
GetContentCaptureReceiver()->DidRemoveContent(data);
}
+void ContentCaptureSender::StartCapture() {
+ render_frame()->GetWebFrame()->SetContentCaptureClient(this);
+}
+
+void ContentCaptureSender::StopCapture() {
+ render_frame()->GetWebFrame()->SetContentCaptureClient(nullptr);
+}
+
void ContentCaptureSender::OnDestruct() {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
diff --git a/chromium/components/content_capture/renderer/content_capture_sender.h b/chromium/components/content_capture/renderer/content_capture_sender.h
index 120cde15696..5d653a0ade4 100644
--- a/chromium/components/content_capture/renderer/content_capture_sender.h
+++ b/chromium/components/content_capture/renderer/content_capture_sender.h
@@ -9,8 +9,13 @@
#include "components/content_capture/common/content_capture.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
#include "third_party/blink/public/web/web_content_capture_client.h"
+namespace blink {
+class AssociatedInterfaceRegistry;
+}
+
namespace content_capture {
struct ContentCaptureData;
@@ -21,11 +26,15 @@ struct ContentCaptureData;
// the ContentCapture in blink by setting WebContentCaptureClient to
// WebLocalFrame.
class ContentCaptureSender : public content::RenderFrameObserver,
- public blink::WebContentCaptureClient {
+ public blink::WebContentCaptureClient,
+ public mojom::ContentCaptureSender {
public:
- explicit ContentCaptureSender(content::RenderFrame* render_frame);
+ explicit ContentCaptureSender(content::RenderFrame* render_frame,
+ blink::AssociatedInterfaceRegistry* registry);
~ContentCaptureSender() override;
+ void BindRequest(mojom::ContentCaptureSenderAssociatedRequest request);
+
// blink::WebContentCaptureClient:
cc::NodeHolder::Type GetNodeHolderType() const override;
void GetTaskTimingParameters(base::TimeDelta& short_delay,
@@ -35,6 +44,10 @@ class ContentCaptureSender : public content::RenderFrameObserver,
bool first_data) override;
void DidRemoveContent(const std::vector<int64_t>& data) override;
+ // mojom::ContentCaptureSender
+ void StartCapture() override;
+ void StopCapture() override;
+
// content::RenderFrameObserver:
void OnDestruct() override;
@@ -44,6 +57,7 @@ class ContentCaptureSender : public content::RenderFrameObserver,
mojom::ContentCaptureReceiverAssociatedPtr content_capture_receiver_ =
nullptr;
+ mojo::AssociatedBinding<mojom::ContentCaptureSender> binding_;
DISALLOW_COPY_AND_ASSIGN(ContentCaptureSender);
};