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 #ifndef mozilla_dom_MIDIPlatformService_h
8 #define mozilla_dom_MIDIPlatformService_h
10 #include "nsClassHashtable.h"
11 #include "mozilla/Mutex.h"
12 #include "mozilla/dom/MIDIPortBinding.h"
13 #include "nsHashKeys.h"
15 // XXX Avoid including this here by moving function implementations to the cpp
17 #include "mozilla/dom/MIDIMessageQueue.h"
19 namespace mozilla::dom
{
21 class MIDIManagerParent
;
24 class MIDIMessageQueue
;
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.
33 class MIDIPlatformService
{
35 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MIDIPlatformService
);
36 // Adds info about MIDI Port that has been connected.
37 void AddPortInfo(MIDIPortInfo
& aPortInfo
);
39 // Removes info of MIDI Port that has been disconnected.
40 void RemovePortInfo(MIDIPortInfo
& aPortInfo
);
42 // Adds a newly created manager protocol object to manager array.
43 void AddManager(MIDIManagerParent
* aManager
);
45 // Removes a deleted manager protocol object from manager array.
46 void RemoveManager(MIDIManagerParent
* aManager
);
48 // Adds a newly created port protocol object to port array.
49 void AddPort(MIDIPortParent
* aPort
);
51 // Removes a deleted port protocol object from port array.
52 void RemovePort(MIDIPortParent
* aPort
);
54 // Platform specific init function.
55 virtual void Init() = 0;
57 // Forces the implementation to refresh the port list.
58 virtual void Refresh() = 0;
60 // Platform specific MIDI port opening function.
61 virtual void Open(MIDIPortParent
* aPort
) = 0;
63 // Clears all queued MIDI messages for a port.
64 void Clear(MIDIPortParent
* aPort
);
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.
71 // Initializes statics on startup.
72 static void InitStatics();
74 // Returns the MIDI Task Queue.
75 static nsISerialEventTarget
* OwnerThread();
77 // Asserts that we're on the above task queue.
78 static void AssertThread() {
79 MOZ_DIAGNOSTIC_ASSERT(OwnerThread()->IsOnCurrentThread());
82 // True if service is live.
83 static bool IsRunning();
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();
89 // Sends a list of all currently connected ports in order to populate a new
93 // Receives a new set of messages from an MIDI Input Port, and checks their
95 void CheckAndReceive(const nsAString
& aPortID
,
96 const nsTArray
<MIDIMessage
>& aMsgs
);
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
);
104 // Adds outgoing messages to the sorted message queue, for sending later.
105 void QueueMessages(const nsAString
& aId
, nsTArray
<MIDIMessage
>& aMsgs
);
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
);
111 // Returns whether there are currently any MIDI devices.
112 bool HasDevice() { return !mPortInfo
.IsEmpty(); }
115 MIDIPlatformService();
116 virtual ~MIDIPlatformService();
117 // Platform specific MIDI service shutdown method.
118 virtual void Stop() = 0;
120 // When device state of a MIDI Port changes, broadcast to all IPC port
122 void BroadcastState(const MIDIPortInfo
& aPortInfo
,
123 const MIDIPortDeviceState
& aState
);
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;
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;
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
);
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
);
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
;
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
;
156 // Array of information for currently connected Ports
157 nsTArray
<MIDIPortInfo
> mPortInfo
;
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.
162 // TODO Split this into input and output ports. Will make life easier.
163 nsTArray
<RefPtr
<MIDIPortParent
>> mPorts
;
165 // Per-port message queue hashtable. Handles scheduling messages for sending.
166 nsClassHashtable
<nsStringHashKey
, MIDIMessageQueue
> mMessageQueues
;
168 // Mutex for managing access to message queue objects.
169 Mutex mMessageQueueMutex MOZ_UNANNOTATED
;
172 } // namespace mozilla::dom
174 #endif // mozilla_dom_MIDIPlatformService_h