MIDIPlatformService.h (6551B)
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/. */ 6 7 #ifndef mozilla_dom_MIDIPlatformService_h 8 #define mozilla_dom_MIDIPlatformService_h 9 10 #include "mozilla/Mutex.h" 11 #include "mozilla/dom/MIDIPortBinding.h" 12 #include "nsClassHashtable.h" 13 #include "nsHashKeys.h" 14 15 // XXX Avoid including this here by moving function implementations to the cpp 16 // file. 17 #include "mozilla/dom/MIDIMessageQueue.h" 18 19 namespace mozilla::dom { 20 21 class MIDIManagerParent; 22 class MIDIPortParent; 23 class MIDIMessage; 24 class MIDIMessageQueue; 25 class MIDIPortInfo; 26 27 /** 28 * Base class for platform specific MIDI implementations. Handles aggregation of 29 * IPC service objects, as well as sending/receiving updates about port 30 * connection events and messages. 31 * 32 */ 33 class MIDIPlatformService { 34 public: 35 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MIDIPlatformService); 36 // Adds info about MIDI Port that has been connected. 37 void AddPortInfo(MIDIPortInfo& aPortInfo); 38 39 // Removes info of MIDI Port that has been disconnected. 40 void RemovePortInfo(MIDIPortInfo& aPortInfo); 41 42 // Adds a newly created manager protocol object to manager array. 43 void AddManager(MIDIManagerParent* aManager); 44 45 // Removes a deleted manager protocol object from manager array. 46 void RemoveManager(MIDIManagerParent* aManager); 47 48 // Adds a newly created port protocol object to port array. 49 void AddPort(MIDIPortParent* aPort); 50 51 // Removes a deleted port protocol object from port array. 52 void RemovePort(MIDIPortParent* aPort); 53 54 // Platform specific init function. 55 virtual void Init() = 0; 56 57 // Forces the implementation to refresh the port list. 58 virtual void Refresh() = 0; 59 60 // Platform specific MIDI port opening function. 61 virtual void Open(MIDIPortParent* aPort) = 0; 62 63 // Clears all queued MIDI messages for a port. 64 void Clear(MIDIPortParent* aPort); 65 66 // Puts in a request to destroy the singleton MIDIPlatformService object. 67 // Object will only be destroyed if there are no more MIDIManager and MIDIPort 68 // protocols left to communicate with. 69 void MaybeStop(); 70 71 // Initializes statics on startup. 72 static void InitStatics(); 73 74 // Returns the MIDI Task Queue. 75 static nsISerialEventTarget* OwnerThread(); 76 77 // Asserts that we're on the above task queue. 78 static void AssertThread() { 79 MOZ_DIAGNOSTIC_ASSERT(OwnerThread()->IsOnCurrentThread()); 80 } 81 82 // True if service is live. 83 static bool IsRunning(); 84 85 // Returns a pointer to the MIDIPlatformService object, creating it and 86 // starting the platform specific service if it is not currently running. 87 static MIDIPlatformService* Get(); 88 89 // Sends a list of all currently connected ports in order to populate a new 90 // MIDIAccess object. 91 void SendPortList(); 92 93 // Receives a new set of messages from an MIDI Input Port, and checks their 94 // validity. 95 void CheckAndReceive(const nsAString& aPortID, 96 const nsTArray<MIDIMessage>& aMsgs); 97 98 // Sends connection/disconnect/open/closed/etc status updates about a MIDI 99 // Port to all port listeners. 100 void UpdateStatus(MIDIPortParent* aPort, 101 const MIDIPortDeviceState& aDeviceState, 102 const MIDIPortConnectionState& aConnectionState); 103 104 // Adds outgoing messages to the sorted message queue, for sending later. 105 void QueueMessages(const nsAString& aId, nsTArray<MIDIMessage>& aMsgs); 106 107 // Clears all messages later than now, sends all outgoing message scheduled 108 // before/at now, and schedules MIDI Port connection closing. 109 void Close(MIDIPortParent* aPort); 110 111 // Returns whether there are currently any MIDI devices. 112 bool HasDevice() { return !mPortInfo.IsEmpty(); } 113 114 protected: 115 MIDIPlatformService(); 116 virtual ~MIDIPlatformService(); 117 // Platform specific MIDI service shutdown method. 118 virtual void Stop() = 0; 119 120 // When device state of a MIDI Port changes, broadcast to all IPC port 121 // objects. 122 void BroadcastState(const MIDIPortInfo& aPortInfo, 123 const MIDIPortDeviceState& aState); 124 125 // Platform specific MIDI port closing function. Named "Schedule" due to the 126 // fact that it needs to happen in the context of the I/O thread for the 127 // platform MIDI implementation, and therefore will happen async. 128 virtual void ScheduleClose(MIDIPortParent* aPort) = 0; 129 130 // Platform specific MIDI message sending function. Named "Schedule" due to 131 // the fact that it needs to happen in the context of the I/O thread for the 132 // platform MIDI implementation, and therefore will happen async. 133 virtual void ScheduleSend(const nsAString& aPortId) = 0; 134 135 // Allows platform specific IO Threads to retrieve all messages to be sent. 136 // Handles mutex locking. 137 void GetMessages(const nsAString& aPortId, nsTArray<MIDIMessage>& aMsgs); 138 139 // Allows platform specific IO Threads to retrieve all messages to be sent 140 // before a certain timestamp. Handles mutex locking. 141 void GetMessagesBefore(const nsAString& aPortId, const TimeStamp& aTimeStamp, 142 nsTArray<MIDIMessage>& aMsgs); 143 144 private: 145 // When the MIDIPlatformService is created, we need to know whether or not the 146 // corresponding IPC MIDIManager objects have received the MIDIPort list after 147 // it is populated. This is set to True when that is done, so we don't 148 // constantly spam MIDIManagers with port lists. 149 bool mHasSentPortList; 150 151 // Array of MIDIManager IPC objects. This array manages the lifetime of 152 // MIDIManager objects in the parent process, and IPC will call 153 // RemoveManager() end lifetime when IPC channel is destroyed. 154 nsTArray<RefPtr<MIDIManagerParent>> mManagers; 155 156 // Array of information for currently connected Ports 157 nsTArray<MIDIPortInfo> mPortInfo; 158 159 // Array of MIDIPort IPC objects. May contain ports not listed in mPortInfo, 160 // as we can hold port objects even after they are disconnected. 161 // 162 // TODO Split this into input and output ports. Will make life easier. 163 nsTArray<RefPtr<MIDIPortParent>> mPorts; 164 165 // Per-port message queue hashtable. Handles scheduling messages for sending. 166 nsClassHashtable<nsStringHashKey, MIDIMessageQueue> mMessageQueues; 167 168 // Mutex for managing access to message queue objects. 169 Mutex mMessageQueueMutex MOZ_UNANNOTATED; 170 }; 171 172 } // namespace mozilla::dom 173 174 #endif // mozilla_dom_MIDIPlatformService_h