Commit e2fd1372 authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Add ability to send user activation context to message port and workers.

As per the latest update to https://github.com/dtapuska/useractivation
exposing the UserActivation on the MessagePort was needed. So this
adds the code and a few tests.

BUG=861735

Change-Id: I3439b67c75e53666243a2ec36d8d93e6c23de5b4
Reviewed-on: https://chromium-review.googlesource.com/1183683
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585195}
parent b5dfa530
<!doctype html>
<title>user activation messagechannel test</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
async_test(function(t) {
var channel = new MessageChannel();
channel.port1.postMessage(1, {includeUserActivation: true});
channel.port1.postMessage(2);
var expected_data = 1;
channel.port2.onmessage = t.step_func(
function(e) {
assert_equals(e.data, expected_data);
expected_data++;
if (e.data == 1) {
assert_false(e.userActivation.isActive);
assert_false(e.userActivation.hasBeenActive);
} else {
assert_equals(e.userActivation, null);
t.done();
}
});
channel.port2.start();
});
</script>
"use strict";
onmessage = e => postMessage(e.userActivation !== null);
<!DOCTYPE html>
<title>postMessage with user activtion to a worker</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
promise_test(async t => {
var worker = new Worker("worker_postMessage_user_activation.js");
let workerReply = () => new Promise((resolve, reject) => {
worker.addEventListener('message', e => resolve(e.data), {once: true});
});
worker.postMessage(null, {includeUserActivation: true});
assert_equals(await workerReply(), true);
worker.postMessage(null, {includeUserActivation: false});
assert_equals(await workerReply(), false);
}, "Post Message from a worker");
</script>
......@@ -714,6 +714,7 @@ interface MessageEvent : Event
getter origin
getter ports
getter source
getter userActivation
method constructor
method initMessageEvent
interface MessagePort : EventTarget
......
......@@ -643,6 +643,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter origin
[Worker] getter ports
[Worker] getter source
[Worker] getter userActivation
[Worker] method constructor
[Worker] method initMessageEvent
[Worker] interface MessagePort : EventTarget
......
......@@ -638,6 +638,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter origin
[Worker] getter ports
[Worker] getter source
[Worker] getter userActivation
[Worker] method constructor
[Worker] method initMessageEvent
[Worker] interface MessagePort : EventTarget
......
......@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/messaging/post_message_options.h"
......@@ -82,4 +84,20 @@ scoped_refptr<SerializedScriptValue> PostMessageHelper::SerializeMessageByCopy(
return serialized_message;
}
mojom::blink::UserActivationSnapshotPtr
PostMessageHelper::CreateUserActivationSnapshot(
ExecutionContext* execution_context,
const PostMessageOptions& options) {
if (!options.includeUserActivation())
return nullptr;
if (LocalDOMWindow* dom_window = execution_context->ExecutingWindow()) {
if (LocalFrame* frame = dom_window->GetFrame()) {
return mojom::blink::UserActivationSnapshot::New(
frame->HasBeenActivated(),
Frame::HasTransientUserActivation(frame, false));
}
}
return nullptr;
}
} // namespace blink
......@@ -6,12 +6,14 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_POST_MESSAGE_HELPER_H_
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/mojom/message_port/message_port.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "v8/include/v8.h"
namespace blink {
class ExecutionContext;
class ExceptionState;
class PostMessageOptions;
class ScriptValue;
......@@ -35,6 +37,12 @@ class CORE_EXPORT PostMessageHelper {
const PostMessageOptions& options,
Transferables& transferables,
ExceptionState&);
// Create a snapshot of the user activation state. Return null if this if the
// execution context is not a window.
static mojom::blink::UserActivationSnapshotPtr CreateUserActivationSnapshot(
ExecutionContext*,
const PostMessageOptions&);
};
} // namespace blink
......
......@@ -101,7 +101,8 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
const String& origin,
const String& last_event_id,
EventTarget* source,
MessagePortArray* ports)
MessagePortArray* ports,
UserActivation* user_activation)
: Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
data_type_(kDataTypeSerializedScriptValue),
data_as_serialized_script_value_(
......@@ -109,7 +110,8 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
origin_(origin),
last_event_id_(last_event_id),
source_(source),
ports_(ports) {
ports_(ports),
user_activation_(user_activation) {
DCHECK(IsValidSource(source_.Get()));
}
......
......@@ -62,7 +62,13 @@ class CORE_EXPORT MessageEvent final : public Event {
const String& last_event_id = String(),
EventTarget* source = nullptr) {
return new MessageEvent(std::move(data), origin, last_event_id, source,
ports);
ports, nullptr);
}
static MessageEvent* Create(MessagePortArray* ports,
scoped_refptr<SerializedScriptValue> data,
UserActivation* user_activation) {
return new MessageEvent(std::move(data), String(), String(), nullptr, ports,
user_activation);
}
static MessageEvent* Create(Vector<MessagePortChannel> channels,
scoped_refptr<SerializedScriptValue> data,
......@@ -201,7 +207,8 @@ class CORE_EXPORT MessageEvent final : public Event {
const String& origin,
const String& last_event_id,
EventTarget* source,
MessagePortArray*);
MessagePortArray*,
UserActivation* user_activation);
MessageEvent(scoped_refptr<SerializedScriptValue> data,
const String& origin,
const String& last_event_id,
......
......@@ -38,7 +38,7 @@
// TODO(bashi): |source| should be (WindowProxy or MessagePort)?
readonly attribute EventTarget? source;
[CachedAttribute=isPortsDirty] readonly attribute FrozenArray<MessagePort> ports;
[Exposed=Window, RuntimeEnabled=UserActivationAPI] readonly attribute UserActivation? userActivation;
[RuntimeEnabled=UserActivationAPI] readonly attribute UserActivation? userActivation;
// TODO(foolip): none of the arguments should have [Default=Undefined] (they
// have other default values in the spec) and |sourceArg|'s type is wrong.
......
......@@ -11,5 +11,5 @@ dictionary MessageEventInit : EventInit {
// TODO(bashi): |source| should be (WindowProxy or MessagePort)?
EventTarget? source;
sequence<MessagePort> ports = [];
[Exposed=Window, RuntimeEnabled=UserActivationAPI] UserActivation? userActivation = null;
[RuntimeEnabled=UserActivationAPI] UserActivation? userActivation = null;
};
......@@ -6,5 +6,4 @@
dictionary WindowPostMessageOptions : PostMessageOptions {
USVString targetOrigin = "/";
[RuntimeEnabled=UserActivationAPI] boolean includeUserActivation = false;
};
......@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/inspector/thread_debugger.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h"
#include "third_party/blink/renderer/core/messaging/post_message_options.h"
......@@ -108,6 +109,8 @@ void MessagePort::postMessage(ScriptState* script_state,
exception_state);
if (exception_state.HadException())
return;
msg.user_activation = PostMessageHelper::CreateUserActivationSnapshot(
GetExecutionContext(), options);
ThreadDebugger* debugger = ThreadDebugger::From(script_state->GetIsolate());
if (debugger)
......@@ -297,7 +300,14 @@ bool MessagePort::Accept(mojo::Message* mojo_message) {
*message.locked_agent_cluster_id)) {
MessagePortArray* ports = MessagePort::EntanglePorts(
*GetExecutionContext(), std::move(message.ports));
evt = MessageEvent::Create(ports, std::move(message.message));
UserActivation* user_activation = nullptr;
if (message.user_activation) {
user_activation =
new UserActivation(message.user_activation->has_been_active,
message.user_activation->was_active);
}
evt = MessageEvent::Create(ports, std::move(message.message),
user_activation);
} else {
evt = MessageEvent::CreateError();
}
......
......@@ -6,4 +6,5 @@
dictionary PostMessageOptions {
sequence<object> transfer = [];
[RuntimeEnabled=UserActivationAPI] boolean includeUserActivation = false;
};
......@@ -152,6 +152,9 @@ void DedicatedWorker::postMessage(ScriptState* script_state,
exception_state);
if (exception_state.HadException())
return;
transferable_message.user_activation =
PostMessageHelper::CreateUserActivationSnapshot(GetExecutionContext(),
options);
transferable_message.sender_stack_trace_id =
ThreadDebugger::From(script_state->GetIsolate())
......
......@@ -84,8 +84,14 @@ void DedicatedWorkerObjectProxy::ProcessMessageFromWorkerObject(
ThreadDebugger* debugger = ThreadDebugger::From(worker_thread->GetIsolate());
debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
global_scope->DispatchEvent(
*MessageEvent::Create(ports, std::move(message.message)));
UserActivation* user_activation = nullptr;
if (message.user_activation) {
user_activation =
new UserActivation(message.user_activation->has_been_active,
message.user_activation->was_active);
}
global_scope->DispatchEvent(*MessageEvent::Create(
ports, std::move(message.message), user_activation));
debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
}
......
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