Commit 0c75d18b authored by Johann's avatar Johann Committed by Commit Bot

webmidi: make MIDIDispatcher garbage collected

Converting MIDIDispatcher also allows us to use the HeapMojo wrappers
to manage the mojo connections.

BUG=chromium:1049056

Change-Id: I1870796a2c99036537f09be71206eeafe59dda11
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2417468Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarTakashi Toyoshima <toyoshim@chromium.org>
Commit-Queue: Johann Koenig <johannkoenig@google.com>
Cr-Commit-Position: refs/heads/master@{#808268}
parent bb156c20
......@@ -60,12 +60,12 @@ PortState ToDeviceState(PortState state) {
} // namespace
MIDIAccess::MIDIAccess(
std::unique_ptr<MIDIDispatcher> dispatcher,
MIDIDispatcher* dispatcher,
bool sysex_enabled,
const Vector<MIDIAccessInitializer::PortDescriptor>& ports,
ExecutionContext* execution_context)
: ExecutionContextLifecycleObserver(execution_context),
dispatcher_(std::move(dispatcher)),
dispatcher_(dispatcher),
sysex_enabled_(sysex_enabled),
has_pending_activity_(false) {
dispatcher_->SetClient(this);
......@@ -84,10 +84,6 @@ MIDIAccess::MIDIAccess(
MIDIAccess::~MIDIAccess() = default;
void MIDIAccess::Dispose() {
dispatcher_.reset();
}
EventListener* MIDIAccess::onstatechange() {
return GetAttributeEventListener(event_type_names::kStatechange);
}
......@@ -202,11 +198,8 @@ void MIDIAccess::SendMIDIData(unsigned port_index,
dispatcher_->SendMIDIData(port_index, data, length, time_stamp);
}
void MIDIAccess::ContextDestroyed() {
dispatcher_.reset();
}
void MIDIAccess::Trace(Visitor* visitor) const {
visitor->Trace(dispatcher_);
visitor->Trace(inputs_);
visitor->Trace(outputs_);
EventTargetWithInlineData::Trace(visitor);
......
......@@ -55,10 +55,9 @@ class MIDIAccess final : public EventTargetWithInlineData,
public ExecutionContextLifecycleObserver,
public MIDIDispatcher::Client {
DEFINE_WRAPPERTYPEINFO();
USING_PRE_FINALIZER(MIDIAccess, Dispose);
public:
MIDIAccess(std::unique_ptr<MIDIDispatcher>,
MIDIAccess(MIDIDispatcher*,
bool sysex_enabled,
const Vector<MIDIAccessInitializer::PortDescriptor>&,
ExecutionContext*);
......@@ -84,7 +83,7 @@ class MIDIAccess final : public EventTargetWithInlineData,
bool HasPendingActivity() const final;
// ExecutionContextLifecycleObserver
void ContextDestroyed() override;
void ContextDestroyed() override {}
// MIDIDispatcher::Client
void DidAddInputPort(const String& id,
......@@ -124,9 +123,7 @@ class MIDIAccess final : public EventTargetWithInlineData,
void Trace(Visitor*) const override;
private:
void Dispose();
std::unique_ptr<MIDIDispatcher> dispatcher_;
Member<MIDIDispatcher> dispatcher_;
bool sysex_enabled_;
bool has_pending_activity_;
HeapVector<Member<MIDIInput>> inputs_;
......
......@@ -34,13 +34,7 @@ MIDIAccessInitializer::MIDIAccessInitializer(ScriptState* script_state,
options_(options),
permission_service_(ExecutionContext::From(script_state)) {}
void MIDIAccessInitializer::Dispose() {
dispatcher_.reset();
}
void MIDIAccessInitializer::ContextDestroyed() {
dispatcher_.reset();
ScriptPromiseResolver::ContextDestroyed();
}
......@@ -108,7 +102,7 @@ void MIDIAccessInitializer::DidStartSession(Result result) {
break;
case Result::OK:
return Resolve(MakeGarbageCollected<MIDIAccess>(
std::move(dispatcher_), options_->hasSysex() && options_->sysex(),
dispatcher_, options_->hasSysex() && options_->sysex(),
port_descriptors_, GetExecutionContext()));
case Result::NOT_SUPPORTED:
return Reject(MakeGarbageCollected<DOMException>(
......@@ -125,6 +119,7 @@ void MIDIAccessInitializer::DidStartSession(Result result) {
}
void MIDIAccessInitializer::Trace(Visitor* visitor) const {
visitor->Trace(dispatcher_);
visitor->Trace(options_);
visitor->Trace(permission_service_);
ScriptPromiseResolver::Trace(visitor);
......@@ -137,7 +132,7 @@ ExecutionContext* MIDIAccessInitializer::GetExecutionContext() const {
void MIDIAccessInitializer::StartSession() {
DCHECK(!dispatcher_);
dispatcher_ = std::make_unique<MIDIDispatcher>(GetExecutionContext());
dispatcher_ = MakeGarbageCollected<MIDIDispatcher>(GetExecutionContext());
dispatcher_->SetClient(this);
}
......
......@@ -24,7 +24,6 @@ class ScriptState;
class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver,
public MIDIDispatcher::Client {
USING_PRE_FINALIZER(MIDIAccessInitializer, Dispose);
public:
struct PortDescriptor {
......@@ -61,8 +60,6 @@ class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver,
MIDIAccessInitializer(ScriptState*, const MIDIOptions*);
~MIDIAccessInitializer() override = default;
void Dispose();
// MIDIDispatcher::Client
void DidAddInputPort(const String& id,
const String& manufacturer,
......@@ -97,7 +94,7 @@ class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver,
void OnPermissionsUpdated(mojom::blink::PermissionStatus);
void OnPermissionUpdated(mojom::blink::PermissionStatus);
std::unique_ptr<MIDIDispatcher> dispatcher_;
Member<MIDIDispatcher> dispatcher_;
Vector<PortDescriptor> port_descriptors_;
Member<const MIDIOptions> options_;
......
......@@ -26,15 +26,20 @@ namespace {
static const size_t kMaxUnacknowledgedBytesSent = 10 * 1024 * 1024; // 10 MB.
} // namespace
MIDIDispatcher::MIDIDispatcher(ExecutionContext* execution_context) {
MIDIDispatcher::MIDIDispatcher(ExecutionContext* execution_context)
: midi_session_(execution_context),
receiver_(this, execution_context),
midi_session_provider_(execution_context) {
TRACE_EVENT0("midi", "MIDIDispatcher::MIDIDispatcher");
// See https://bit.ly/2S0zRAS for task types.
execution_context->GetBrowserInterfaceBroker().GetInterface(
midi_session_provider_.BindNewPipeAndPassReceiver(
execution_context->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)));
midi_session_provider_->StartSession(
midi_session_.BindNewPipeAndPassReceiver(),
receiver_.BindNewPipeAndPassRemote());
midi_session_.BindNewPipeAndPassReceiver(
execution_context->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)),
receiver_.BindNewPipeAndPassRemote(
execution_context->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)));
}
MIDIDispatcher::~MIDIDispatcher() = default;
......@@ -132,4 +137,10 @@ void MIDIDispatcher::DataReceived(uint32_t port,
client_->DidReceiveMIDIData(port, &data[0], data.size(), timestamp);
}
void MIDIDispatcher::Trace(Visitor* visitor) const {
visitor->Trace(midi_session_);
visitor->Trace(receiver_);
visitor->Trace(midi_session_provider_);
}
} // namespace blink
......@@ -6,15 +6,16 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_DISPATCHER_H_
#include "media/midi/midi_service.mojom-blink.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class MIDIDispatcher : public midi::mojom::blink::MidiSessionClient {
class MIDIDispatcher : public GarbageCollected<MIDIDispatcher>,
public midi::mojom::blink::MidiSessionClient {
public:
class Client {
public:
......@@ -40,8 +41,7 @@ class MIDIDispatcher : public midi::mojom::blink::MidiSessionClient {
base::TimeTicks time_stamp) = 0;
};
explicit MIDIDispatcher(
ExecutionContext* execution_context);
explicit MIDIDispatcher(ExecutionContext* execution_context);
~MIDIDispatcher() override;
void SetClient(Client* client) { client_ = client; }
......@@ -65,6 +65,8 @@ class MIDIDispatcher : public midi::mojom::blink::MidiSessionClient {
const Vector<uint8_t>& data,
base::TimeTicks timestamp) override;
void Trace(Visitor* visitor) const;
private:
Client* client_ = nullptr;
......@@ -77,12 +79,12 @@ class MIDIDispatcher : public midi::mojom::blink::MidiSessionClient {
// TODO(toyoshim): Consider to have a per-process limit.
size_t unacknowledged_bytes_sent_ = 0u;
// TODO(1049056): Now that MidiSession is passed an ExecutionContext use it to
// convert these to HeapMojo.
mojo::Remote<midi::mojom::blink::MidiSession> midi_session_;
HeapMojoRemote<midi::mojom::blink::MidiSession> midi_session_;
mojo::Receiver<midi::mojom::blink::MidiSessionClient> receiver_{this};
mojo::Remote<midi::mojom::blink::MidiSessionProvider> midi_session_provider_;
HeapMojoReceiver<midi::mojom::blink::MidiSessionClient, MIDIDispatcher>
receiver_;
HeapMojoRemote<midi::mojom::blink::MidiSessionProvider>
midi_session_provider_;
};
} // namespace blink
......
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