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_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 // Platform specific MIDI port opening function.
58 virtual void Open(MIDIPortParent
* aPort
) = 0;
60 // Clears all queued MIDI messages for a port.
61 void Clear(MIDIPortParent
* aPort
);
63 // Puts in a request to destroy the singleton MIDIPlatformService object.
64 // Object will only be destroyed if there are no more MIDIManager and MIDIPort
65 // protocols left to communicate with.
68 // True if service is live.
69 static bool IsRunning();
71 // Returns a pointer to the MIDIPlatformService object, creating it and
72 // starting the platform specific service if it is not currently running.
73 static MIDIPlatformService
* Get();
75 // Sends a list of all currently connected ports in order to populate a new
79 // Receives a new set of messages from an MIDI Input Port, and checks their
81 void CheckAndReceive(const nsAString
& aPortID
,
82 const nsTArray
<MIDIMessage
>& aMsgs
);
84 // Sends connection/disconnect/open/closed/etc status updates about a MIDI
85 // Port to all port listeners.
86 void UpdateStatus(MIDIPortParent
* aPort
,
87 const MIDIPortDeviceState
& aDeviceState
,
88 const MIDIPortConnectionState
& aConnectionState
);
90 // Adds outgoing messages to the sorted message queue, for sending later.
91 void QueueMessages(const nsAString
& aId
, nsTArray
<MIDIMessage
>& aMsgs
);
93 // Clears all messages later than now, sends all outgoing message scheduled
94 // before/at now, and schedules MIDI Port connection closing.
95 void Close(MIDIPortParent
* aPort
);
98 MIDIPlatformService();
99 virtual ~MIDIPlatformService();
100 // Platform specific MIDI service shutdown method.
101 virtual void Stop() = 0;
103 // When device state of a MIDI Port changes, broadcast to all IPC port
105 void BroadcastState(const MIDIPortInfo
& aPortInfo
,
106 const MIDIPortDeviceState
& aState
);
108 // Platform specific MIDI port closing function. Named "Schedule" due to the
109 // fact that it needs to happen in the context of the I/O thread for the
110 // platform MIDI implementation, and therefore will happen async.
111 virtual void ScheduleClose(MIDIPortParent
* aPort
) = 0;
113 // Platform specific MIDI message sending function. Named "Schedule" due to
114 // the fact that it needs to happen in the context of the I/O thread for the
115 // platform MIDI implementation, and therefore will happen async.
116 virtual void ScheduleSend(const nsAString
& aPortId
) = 0;
118 // Allows platform specific IO Threads to retrieve all messages to be sent.
119 // Handles mutex locking.
120 void GetMessages(const nsAString
& aPortId
, nsTArray
<MIDIMessage
>& aMsgs
);
122 // Allows platform specific IO Threads to retrieve all messages to be sent
123 // before a certain timestamp. Handles mutex locking.
124 void GetMessagesBefore(const nsAString
& aPortId
, const TimeStamp
& aTimeStamp
,
125 nsTArray
<MIDIMessage
>& aMsgs
);
128 // When the MIDIPlatformService is created, we need to know whether or not the
129 // corresponding IPC MIDIManager objects have received the MIDIPort list after
130 // it is populated. This is set to True when that is done, so we don't
131 // constantly spam MIDIManagers with port lists.
132 bool mHasSentPortList
;
134 // Array of MIDIManager IPC objects. This array manages the lifetime of
135 // MIDIManager objects in the parent process, and IPC will call
136 // RemoveManager() end lifetime when IPC channel is destroyed.
137 nsTArray
<RefPtr
<MIDIManagerParent
>> mManagers
;
139 // Array of information for currently connected Ports
140 nsTArray
<MIDIPortInfo
> mPortInfo
;
142 // Array of MIDIPort IPC objects. May contain ports not listed in mPortInfo,
143 // as we can hold port objects even after they are disconnected.
145 // TODO Split this into input and output ports. Will make life easier.
146 nsTArray
<RefPtr
<MIDIPortParent
>> mPorts
;
148 // Per-port message queue hashtable. Handles scheduling messages for sending.
149 nsClassHashtable
<nsStringHashKey
, MIDIMessageQueue
> mMessageQueues
;
151 // Mutex for managing access to message queue objects.
152 Mutex mMessageQueueMutex
;
155 } // namespace mozilla::dom
157 #endif // mozilla_dom_MIDIPlatformService_h