Classify UMA data for extension messaging user activation triggering.
Split the UMA entry for extension messaging user activation triggering
into four classes, based on whether the script contexts of the sender
and the receiver are privileged or not.
(cherry picked from commit 15f771dc66ec67b2f1f311dbbf8035b975b2666d)
Bug: 1103249, 1047473
Change-Id: Ib23bf2e9427d2b836cdc21c1cf9ebbd685e27299
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2461251
Commit-Queue: Mustaq Ahmed <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Mustaq Ahmed <[email protected]>
Reviewed-by: Devlin <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#817247}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2485012
Cr-Commit-Position: refs/branch-heads/4280@{#489}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/extensions/common/api/messaging/message.h b/extensions/common/api/messaging/message.h
index 3f34e66..c3ff586 100644
--- a/extensions/common/api/messaging/message.h
+++ b/extensions/common/api/messaging/message.h
@@ -10,13 +10,20 @@
// A message consists of both the data itself as well as a user gesture state.
struct Message {
std::string data;
- bool user_gesture;
+ bool user_gesture = false;
+ bool from_privileged_context = false;
- Message() : data(), user_gesture(false) {}
- Message(const std::string& data, bool user_gesture)
- : data(data), user_gesture(user_gesture) {}
+ Message() = default;
+ Message(const std::string& data,
+ bool user_gesture,
+ bool from_privileged_context = false)
+ : data(data),
+ user_gesture(user_gesture),
+ from_privileged_context(from_privileged_context) {}
bool operator==(const Message& other) const {
+ // Skipping the equality check for |from_privileged_context| here
+ // because this field is used only for histograms.
return data == other.data && user_gesture == other.user_gesture;
}
};
diff --git a/extensions/renderer/messaging_util.cc b/extensions/renderer/messaging_util.cc
index 91b5b271..f6bf874 100644
--- a/extensions/renderer/messaging_util.cc
+++ b/extensions/renderer/messaging_util.cc
@@ -81,14 +81,18 @@
ScriptContext* script_context = GetScriptContextFromV8Context(context);
blink::WebLocalFrame* web_frame =
script_context ? script_context->web_frame() : nullptr;
- return MessageFromJSONString(isolate, stringified, error_out, web_frame);
+ bool privileged_context =
+ script_context && script_context->context_type() ==
+ extensions::Feature::BLESSED_EXTENSION_CONTEXT;
+ return MessageFromJSONString(isolate, stringified, error_out, web_frame,
+ privileged_context);
}
-std::unique_ptr<Message> MessageFromJSONString(
- v8::Isolate* isolate,
- v8::Local<v8::String> json,
- std::string* error_out,
- blink::WebLocalFrame* web_frame) {
+std::unique_ptr<Message> MessageFromJSONString(v8::Isolate* isolate,
+ v8::Local<v8::String> json,
+ std::string* error_out,
+ blink::WebLocalFrame* web_frame,
+ bool privileged_context) {
std::string message;
message = gin::V8ToString(isolate, json);
// JSON.stringify can fail to produce a string value in one of two ways: it
@@ -122,7 +126,8 @@
bool has_transient_user_activation =
web_frame ? web_frame->HasTransientUserActivation() : false;
- return std::make_unique<Message>(message, has_transient_user_activation);
+ return std::make_unique<Message>(message, has_transient_user_activation,
+ privileged_context);
}
v8::Local<v8::Value> MessageToV8(v8::Local<v8::Context> context,
diff --git a/extensions/renderer/messaging_util.h b/extensions/renderer/messaging_util.h
index 35cbbc0..7a381b4 100644
--- a/extensions/renderer/messaging_util.h
+++ b/extensions/renderer/messaging_util.h
@@ -44,7 +44,8 @@
std::unique_ptr<Message> MessageFromJSONString(v8::Isolate* isolate,
v8::Local<v8::String> json,
std::string* error,
- blink::WebLocalFrame* web_frame);
+ blink::WebLocalFrame* web_frame,
+ bool privileged_context);
// Converts a message to a v8 value. This is expected not to fail, since it
// should only be used for messages that have been validated.
diff --git a/extensions/renderer/native_renderer_messaging_service.cc b/extensions/renderer/native_renderer_messaging_service.cc
index 4fab856..6d78a71 100644
--- a/extensions/renderer/native_renderer_messaging_service.cc
+++ b/extensions/renderer/native_renderer_messaging_service.cc
@@ -20,6 +20,7 @@
#include "extensions/common/api/messaging/messaging_endpoint.h"
#include "extensions/common/api/messaging/port_id.h"
#include "extensions/common/extension_messages.h"
+#include "extensions/common/features/feature.h"
#include "extensions/common/manifest_handlers/externally_connectable.h"
#include "extensions/renderer/api_activity_logger.h"
#include "extensions/renderer/bindings/api_binding_util.h"
@@ -41,6 +42,8 @@
#include "third_party/blink/public/web/web_scoped_window_focus_allowed_indicator.h"
#include "v8/include/v8.h"
+using blink::mojom::UserActivationNotificationType;
+
namespace extensions {
namespace {
@@ -317,9 +320,26 @@
std::unique_ptr<blink::WebScopedWindowFocusAllowedIndicator>
allow_window_focus;
if (message.user_gesture && script_context->web_frame()) {
- // TODO(mustaq): Split this further for trusted/untrusted cases.
- script_context->web_frame()->NotifyUserActivation(
- blink::mojom::UserActivationNotificationType::kExtensionMessaging);
+ bool sender_is_privileged = message.from_privileged_context;
+ bool receiver_is_privileged =
+ script_context->context_type() ==
+ extensions::Feature::BLESSED_EXTENSION_CONTEXT;
+ UserActivationNotificationType notification_type;
+ if (sender_is_privileged && receiver_is_privileged) {
+ notification_type =
+ UserActivationNotificationType::kExtensionMessagingBothPrivileged;
+ } else if (sender_is_privileged && !receiver_is_privileged) {
+ notification_type =
+ UserActivationNotificationType::kExtensionMessagingSenderPrivileged;
+ } else if (!sender_is_privileged && receiver_is_privileged) {
+ notification_type =
+ UserActivationNotificationType::kExtensionMessagingReceiverPrivileged;
+ } else /* !sender_is_privileged && !receiver_is_privileged */ {
+ notification_type =
+ UserActivationNotificationType::kExtensionMessagingNeitherPrivileged;
+ }
+
+ script_context->web_frame()->NotifyUserActivation(notification_type);
blink::WebDocument document = script_context->web_frame()->GetDocument();
allow_window_focus =
diff --git a/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom b/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom
index 7e6f3b1..bf7ef0d5 100644
--- a/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom
+++ b/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom
@@ -24,7 +24,9 @@
// An extension API caused the notification call through GuestView.
kExtensionGuestView,
- // An extension messaging API caused the notification call.
+ // An extension messaging API caused the notification call. This enum value
+ // is deprecated by more specific enums kExtensionMessaging* below, we are
+ // preserving this enum value only for UMA consistency.
kExtensionMessaging,
// A media API caused the notification call.
@@ -47,5 +49,24 @@
kWebScriptExec,
// Android voice search API caused the notification call.
- kVoiceSearch
+ kVoiceSearch,
+
+ // An extension messaging API caused the notification call, where the script
+ // contexts of both the sender and the receiver of the message are privileged.
+ kExtensionMessagingBothPrivileged,
+
+ // An extension messaging API caused the notification call, where the script
+ // context of only the sender (and not the receiver) of the message is
+ // privileged.
+ kExtensionMessagingSenderPrivileged,
+
+ // An extension messaging API caused the notification call, where the script
+ // context of only the receiver (and not the sender) of the message is
+ // privileged.
+ kExtensionMessagingReceiverPrivileged,
+
+ // An extension messaging API caused the notification call, where the script
+ // context of neither the sender nor the receiver of the message is
+ // privileged.
+ kExtensionMessagingNeitherPrivileged
};
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 674d307..3fcbad9 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -72975,6 +72975,10 @@
<int value="9" label="kTest"/>
<int value="10" label="kWebScriptExec"/>
<int value="11" label="kVoiceSearch"/>
+ <int value="12" label="kExtensionMessagingBothPrivileged"/>
+ <int value="13" label="kExtensionMessagingSenderPrivileged"/>
+ <int value="14" label="kExtensionMessagingReceiverPrivileged"/>
+ <int value="15" label="kExtensionMessagingNeitherPrivileged"/>
</enum>
<enum name="UserCertContentDisposition">