1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_ 6 #define CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "content/common/content_export.h" 13 #include "ipc/message_filter.h" 14 #include "media/midi/midi_port_info.h" 15 #include "media/midi/midi_result.h" 16 #include "third_party/WebKit/public/platform/WebMIDIAccessorClient.h" 17 18 namespace base { 19 class MessageLoopProxy; 20 } 21 22 namespace content { 23 24 // MessageFilter that handles MIDI messages. 25 class CONTENT_EXPORT MidiMessageFilter : public IPC::MessageFilter { 26 public: 27 explicit MidiMessageFilter( 28 const scoped_refptr<base::MessageLoopProxy>& io_message_loop); 29 30 // Each client registers for MIDI access here. 31 // If permission is granted, then the client's 32 // addInputPort() and addOutputPort() methods will be called, 33 // giving the client access to receive and send data. 34 void StartSession(blink::WebMIDIAccessorClient* client); 35 void RemoveClient(blink::WebMIDIAccessorClient* client); 36 37 // A client will only be able to call this method if it has a suitable 38 // output port (from addOutputPort()). 39 void SendMidiData(uint32 port, 40 const uint8* data, 41 size_t length, 42 double timestamp); 43 44 // IO message loop associated with this message filter. 45 scoped_refptr<base::MessageLoopProxy> io_message_loop() const { 46 return io_message_loop_; 47 } 48 49 protected: 50 virtual ~MidiMessageFilter(); 51 52 private: 53 // Sends an IPC message using |sender_|. 54 void Send(IPC::Message* message); 55 56 // IPC::MessageFilter override. Called on |io_message_loop|. 57 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 58 virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE; 59 virtual void OnFilterRemoved() OVERRIDE; 60 virtual void OnChannelClosing() OVERRIDE; 61 62 // Called when the browser process has approved (or denied) access to 63 // MIDI hardware. 64 void OnSessionStarted(int client_id, 65 media::MidiResult result, 66 media::MidiPortInfoList inputs, 67 media::MidiPortInfoList outputs); 68 69 // Called when the browser process has sent MIDI data containing one or 70 // more messages. 71 void OnDataReceived(uint32 port, 72 const std::vector<uint8>& data, 73 double timestamp); 74 75 // From time-to-time, the browser incrementally informs us of how many bytes 76 // it has successfully sent. This is part of our throttling process to avoid 77 // sending too much data before knowing how much has already been sent. 78 void OnAcknowledgeSentData(size_t bytes_sent); 79 80 void HandleSessionStarted(int client_id, 81 media::MidiResult result, 82 media::MidiPortInfoList inputs, 83 media::MidiPortInfoList outputs); 84 85 void HandleDataReceived(uint32 port, 86 const std::vector<uint8>& data, 87 double timestamp); 88 89 void StartSessionOnIOThread(int client_id); 90 91 void SendMidiDataOnIOThread(uint32 port, 92 const std::vector<uint8>& data, 93 double timestamp); 94 95 blink::WebMIDIAccessorClient* GetClientFromId(int client_id); 96 97 // IPC sender for Send(); must only be accessed on |io_message_loop_|. 98 IPC::Sender* sender_; 99 100 // Message loop on which IPC calls are driven. 101 const scoped_refptr<base::MessageLoopProxy> io_message_loop_; 102 103 // Main thread's message loop. 104 scoped_refptr<base::MessageLoopProxy> main_message_loop_; 105 106 // Keeps track of all MIDI clients. 107 // We map client to "client id" used to track permission. 108 // When access has been approved, we add the input and output ports to 109 // the client, allowing it to actually receive and send MIDI data. 110 typedef std::map<blink::WebMIDIAccessorClient*, int> ClientsMap; 111 ClientsMap clients_; 112 113 // Dishes out client ids. 114 int next_available_id_; 115 116 size_t unacknowledged_bytes_sent_; 117 118 DISALLOW_COPY_AND_ASSIGN(MidiMessageFilter); 119 }; 120 121 } // namespace content 122 123 #endif // CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_ 124