DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
/* -*- 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);

 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