Bug 1835529 [wpt PR 40276] - Update wpt metadata, a=testonly
[gecko.git] / dom / midi / MIDIInput.cpp
blobdbd46fa843102f8c2de63d40ee4d025d0ee54423
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/MIDIInput.h"
8 #include "mozilla/dom/Document.h"
9 #include "mozilla/dom/MIDIPortChild.h"
10 #include "mozilla/dom/MIDIInputBinding.h"
11 #include "mozilla/dom/MIDIMessageEvent.h"
12 #include "mozilla/dom/MIDIMessageEventBinding.h"
13 #include "nsDOMNavigationTiming.h"
15 #include "MIDILog.h"
17 namespace mozilla::dom {
19 MIDIInput::MIDIInput(nsPIDOMWindowInner* aWindow, MIDIAccess* aMIDIAccessParent)
20 : MIDIPort(aWindow, aMIDIAccessParent), mKeepAlive(false) {}
22 // static
23 MIDIInput* MIDIInput::Create(nsPIDOMWindowInner* aWindow,
24 MIDIAccess* aMIDIAccessParent,
25 const MIDIPortInfo& aPortInfo,
26 const bool aSysexEnabled) {
27 MOZ_ASSERT(static_cast<MIDIPortType>(aPortInfo.type()) ==
28 MIDIPortType::Input);
29 auto* port = new MIDIInput(aWindow, aMIDIAccessParent);
30 if (!port->Initialize(aPortInfo, aSysexEnabled)) {
31 return nullptr;
33 return port;
36 JSObject* MIDIInput::WrapObject(JSContext* aCx,
37 JS::Handle<JSObject*> aGivenProto) {
38 return MIDIInput_Binding::Wrap(aCx, this, aGivenProto);
41 void MIDIInput::Receive(const nsTArray<MIDIMessage>& aMsgs) {
42 if (!GetOwner()) {
43 return; // Ignore messages once we've been disconnected from the owner
46 nsCOMPtr<Document> doc = GetOwner()->GetDoc();
47 if (!doc) {
48 NS_WARNING("No document available to send MIDIMessageEvent to!");
49 return;
51 for (const auto& msg : aMsgs) {
52 RefPtr<MIDIMessageEvent> event(
53 MIDIMessageEvent::Constructor(this, msg.timestamp(), msg.data()));
54 DispatchTrustedEvent(event);
58 void MIDIInput::StateChange() {
59 if (Port()->ConnectionState() == MIDIPortConnectionState::Open ||
60 (Port()->DeviceState() == MIDIPortDeviceState::Connected &&
61 Port()->ConnectionState() == MIDIPortConnectionState::Pending)) {
62 KeepAliveOnMidimessage();
63 } else {
64 DontKeepAliveOnMidimessage();
68 void MIDIInput::EventListenerAdded(nsAtom* aType) {
69 if (aType == nsGkAtoms::onmidimessage) {
70 // HACK: the Web MIDI spec states that we should open a port only when
71 // setting the midimessage event handler but Chrome does it even when
72 // adding event listeners hence this.
73 if (Port()->ConnectionState() != MIDIPortConnectionState::Open) {
74 LOG("onmidimessage event listener added, sending implicit Open");
75 Port()->SendOpen();
79 DOMEventTargetHelper::EventListenerAdded(aType);
82 void MIDIInput::DisconnectFromOwner() {
83 DontKeepAliveOnMidimessage();
85 MIDIPort::DisconnectFromOwner();
88 void MIDIInput::KeepAliveOnMidimessage() {
89 if (!mKeepAlive) {
90 mKeepAlive = true;
91 KeepAliveIfHasListenersFor(nsGkAtoms::onmidimessage);
95 void MIDIInput::DontKeepAliveOnMidimessage() {
96 if (mKeepAlive) {
97 IgnoreKeepAliveIfHasListenersFor(nsGkAtoms::onmidimessage);
98 mKeepAlive = false;
102 } // namespace mozilla::dom