/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_MIDIAccess_h #define mozilla_dom_MIDIAccess_h #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/ErrorResult.h" #include "mozilla/Observer.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" struct JSContext; namespace mozilla { // Predeclare void_t here, as including IPCMessageUtils brings in windows.h and // causes binding compilation problems. struct void_t; namespace dom { class MIDIAccessManager; class MIDIInputMap; struct MIDIOptions; class MIDIOutputMap; class MIDIPermissionRequest; class MIDIPort; class MIDIPortChangeEvent; class MIDIPortInfo; class MIDIPortList; class Promise; typedef Observer MIDIAccessDestructionObserver; /** * MIDIAccess is the DOM object that is handed to the user upon MIDI permissions * being successfully granted. It manages access to MIDI ports, and fires events * for device connection and disconnection. * * New MIDIAccess objects are created every time RequestMIDIAccess is called. * MIDIAccess objects are managed via MIDIAccessManager. */ class MIDIAccess final : public DOMEventTargetHelper, public Observer { // Use the Permission Request class in MIDIAccessManager for creating // MIDIAccess objects. friend class MIDIPermissionRequest; friend class MIDIAccessManager; public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MIDIAccess, DOMEventTargetHelper) public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; // Return map of MIDI Input Ports MIDIInputMap* Inputs() const { return mInputMap; } // Return map of MIDI Output Ports MIDIOutputMap* Outputs() const { return mOutputMap; } // Returns true if sysex permissions were given bool SysexEnabled() const { return mSysexEnabled; } // Observer implementation for receiving port connection updates void Notify(const MIDIPortList& aEvent) override; // All MIDIPort objects observe destruction of the MIDIAccess object that // created them, as the port object receives disconnection events which then // must be passed up to the MIDIAccess object. If the Port object dies before // the MIDIAccess object, it needs to be removed from the observer list. void RemovePortListener(MIDIAccessDestructionObserver* aPort); // Fires DOM event on port connection/disconnection void FireConnectionEvent(MIDIPort* aPort); // Notify all MIDIPorts that were created by this MIDIAccess and are still // alive, and detach from the MIDIAccessManager. void Shutdown(); IMPL_EVENT_HANDLER(statechange); private: MIDIAccess(nsPIDOMWindowInner* aWindow, bool aSysexEnabled, Promise* aAccessPromise); ~MIDIAccess(); // On receiving a connection event from MIDIAccessManager, create a // corresponding MIDIPort object if we don't already have one. void MaybeCreateMIDIPort(const MIDIPortInfo& aInfo, ErrorResult& aRv); // Stores all known MIDIInput Ports RefPtr mInputMap; // Stores all known MIDIOutput Ports RefPtr mOutputMap; // List of MIDIPort observers that need to be updated on destruction. ObserverList mDestructionObservers; // True if user gave permissions for sysex usage to this object. bool mSysexEnabled; // Promise created by RequestMIDIAccess call, to be resolved after port // populating is finished. RefPtr mAccessPromise; // True if shutdown process has started, so we don't try to add more ports. bool mHasShutdown; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_MIDIAccess_h