2017-11-15 22:19:59 +03:00
|
|
|
/* -*- 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_MIDIPlatformService_h
|
|
|
|
#define mozilla_dom_MIDIPlatformService_h
|
|
|
|
|
|
|
|
#include "nsClassHashtable.h"
|
|
|
|
#include "mozilla/dom/MIDIPortBinding.h"
|
|
|
|
#include "mozilla/dom/MIDITypes.h"
|
|
|
|
#include "mozilla/dom/MIDIPortInterface.h"
|
|
|
|
#include "nsHashKeys.h"
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
class MIDIManagerParent;
|
|
|
|
class MIDIPortParent;
|
|
|
|
class MIDIMessageQueue;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Base class for platform specific MIDI implementations. Handles aggregation of
|
|
|
|
* IPC service objects, as well as sending/receiving updates about port
|
|
|
|
* connection events and messages.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class MIDIPlatformService {
|
|
|
|
public:
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(MIDIPlatformService);
|
|
|
|
// Adds info about MIDI Port that has been connected.
|
|
|
|
void AddPortInfo(MIDIPortInfo& aPortInfo);
|
|
|
|
|
|
|
|
// Removes info of MIDI Port that has been disconnected.
|
|
|
|
void RemovePortInfo(MIDIPortInfo& aPortInfo);
|
|
|
|
|
|
|
|
// Adds a newly created manager protocol object to manager array.
|
|
|
|
void AddManager(MIDIManagerParent* aParent);
|
|
|
|
|
|
|
|
// Removes a deleted manager protocol object from manager array.
|
|
|
|
void RemoveManager(MIDIManagerParent* aParent);
|
|
|
|
|
|
|
|
// Adds a newly created port protocol object to port array.
|
|
|
|
void AddPort(MIDIPortParent* aPort);
|
|
|
|
|
|
|
|
// Removes a deleted port protocol object from port array.
|
|
|
|
void RemovePort(MIDIPortParent* aPort);
|
|
|
|
|
|
|
|
// Platform specific init function.
|
|
|
|
virtual void Init() = 0;
|
|
|
|
|
|
|
|
// Platform specific MIDI port opening function.
|
|
|
|
virtual void Open(MIDIPortParent* aPort) = 0;
|
|
|
|
|
|
|
|
// Clears all queued MIDI messages for a port.
|
|
|
|
void Clear(MIDIPortParent* aPort);
|
|
|
|
|
|
|
|
// Puts in a request to destroy the singleton MIDIPlatformService object.
|
|
|
|
// Object will only be destroyed if there are no more MIDIManager and MIDIPort
|
|
|
|
// protocols left to communicate with.
|
|
|
|
void MaybeStop();
|
|
|
|
|
|
|
|
// True if service is live.
|
|
|
|
static bool IsRunning();
|
|
|
|
|
|
|
|
// Returns a pointer to the MIDIPlatformService object, creating it and
|
|
|
|
// starting the platform specific service if it is not currently running.
|
|
|
|
static MIDIPlatformService* Get();
|
|
|
|
|
|
|
|
// Sends a list of all currently connected ports in order to populate a new
|
|
|
|
// MIDIAccess object.
|
|
|
|
void SendPortList();
|
|
|
|
|
|
|
|
// Receives a new set of messages from an MIDI Input Port, and checks their
|
|
|
|
// validity.
|
|
|
|
void CheckAndReceive(const nsAString& aPortID,
|
|
|
|
const nsTArray<MIDIMessage>& aMsgs);
|
|
|
|
|
|
|
|
// Sends connection/disconnect/open/closed/etc status updates about a MIDI
|
|
|
|
// Port to all port listeners.
|
|
|
|
void UpdateStatus(MIDIPortParent* aPort,
|
|
|
|
const MIDIPortDeviceState& aDeviceState,
|
|
|
|
const MIDIPortConnectionState& aConnectionState);
|
|
|
|
void UpdateStatus(const nsAString& aPortId,
|
|
|
|
const MIDIPortDeviceState& aDeviceState,
|
|
|
|
const MIDIPortConnectionState& aConnectionState);
|
|
|
|
|
|
|
|
// Adds outgoing messages to the sorted message queue, for sending later.
|
|
|
|
void QueueMessages(const nsAString& aId, nsTArray<MIDIMessage>& aMsgs);
|
|
|
|
|
|
|
|
// Clears all messages later than now, sends all outgoing message scheduled
|
|
|
|
// before/at now, and schedules MIDI Port connection closing.
|
|
|
|
void Close(MIDIPortParent* aPort);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-11-15 22:19:59 +03:00
|
|
|
protected:
|
|
|
|
MIDIPlatformService();
|
|
|
|
virtual ~MIDIPlatformService();
|
|
|
|
// Platform specific MIDI service shutdown method.
|
|
|
|
virtual void Stop() = 0;
|
|
|
|
|
|
|
|
// When device state of a MIDI Port changes, broadcast to all IPC port
|
|
|
|
// objects.
|
|
|
|
void BroadcastState(const MIDIPortInfo& aPortInfo,
|
|
|
|
const MIDIPortDeviceState& aState);
|
|
|
|
|
|
|
|
// Platform specific MIDI port closing function. Named "Schedule" due to the
|
|
|
|
// fact that it needs to happen in the context of the I/O thread for the
|
|
|
|
// platform MIDI implementation, and therefore will happen async.
|
|
|
|
virtual void ScheduleClose(MIDIPortParent* aPort) = 0;
|
|
|
|
|
|
|
|
// Platform specific MIDI message sending function. Named "Schedule" due to
|
|
|
|
// the fact that it needs to happen in the context of the I/O thread for the
|
|
|
|
// platform MIDI implementation, and therefore will happen async.
|
|
|
|
virtual void ScheduleSend(const nsAString& aPortId) = 0;
|
|
|
|
|
|
|
|
// Allows platform specific IO Threads to retrieve all messages to be sent.
|
|
|
|
// Handles mutex locking.
|
|
|
|
void GetMessages(const nsAString& aPortId, nsTArray<MIDIMessage>& aMsgs);
|
|
|
|
|
|
|
|
// Allows platform specific IO Threads to retrieve all messages to be sent
|
|
|
|
// before a certain timestamp. Handles mutex locking.
|
|
|
|
void GetMessagesBefore(const nsAString& aPortId, const TimeStamp& aTimeStamp,
|
|
|
|
nsTArray<MIDIMessage>& aMsgs);
|
|
|
|
|
|
|
|
private:
|
|
|
|
// When the MIDIPlatformService is created, we need to know whether or not the
|
|
|
|
// corresponding IPC MIDIManager objects have received the MIDIPort list after
|
|
|
|
// it is populated. This is set to True when that is done, so we don't
|
|
|
|
// constantly spam MIDIManagers with port lists.
|
|
|
|
bool mHasSentPortList;
|
|
|
|
|
|
|
|
// Array of MIDIManager IPC objects. This array manages the lifetime of
|
|
|
|
// MIDIManager objects in the parent process, and IPC will call
|
|
|
|
// RemoveManager() end lifetime when IPC channel is destroyed.
|
|
|
|
nsTArray<RefPtr<MIDIManagerParent>> mManagers;
|
|
|
|
|
|
|
|
// Array of information for currently connected Ports
|
|
|
|
nsTArray<MIDIPortInfo> mPortInfo;
|
|
|
|
|
|
|
|
// Array of MIDIPort IPC objects. May contain ports not listed in mPortInfo,
|
|
|
|
// as we can hold port objects even after they are disconnected.
|
|
|
|
//
|
|
|
|
// TODO Split this into input and output ports. Will make life easier.
|
|
|
|
nsTArray<RefPtr<MIDIPortParent>> mPorts;
|
|
|
|
|
|
|
|
// Per-port message queue hashtable. Handles scheduling messages for sending.
|
|
|
|
nsClassHashtable<nsStringHashKey, MIDIMessageQueue> mMessageQueues;
|
|
|
|
|
|
|
|
// Mutex for managing access to message queue objects.
|
|
|
|
Mutex mMessageQueueMutex;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_MIDIPlatformService_h
|