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/ipc_channel_proxy.h" 14 #include "media/midi/midi_port_info.h" 15 #include "third_party/WebKit/public/platform/WebMIDIAccessor.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 26 : public IPC::ChannelProxy::MessageFilter { 27 public: 28 explicit MIDIMessageFilter( 29 const scoped_refptr<base::MessageLoopProxy>& io_message_loop); 30 31 // Each client registers for MIDI access here. 32 // If permission is granted, then the client's 33 // addInputPort() and addOutputPort() methods will be called, 34 // giving the client access to receive and send data. 35 void StartSession(WebKit::WebMIDIAccessorClient* client); 36 void RemoveClient(WebKit::WebMIDIAccessorClient* client); 37 38 // A client will only be able to call this method if it has a suitable 39 // output port (from addOutputPort()). 40 void SendMIDIData(int port, 41 const uint8* data, 42 size_t length, 43 double timestamp); 44 45 // IO message loop associated with this message filter. 46 scoped_refptr<base::MessageLoopProxy> io_message_loop() const { 47 return io_message_loop_; 48 } 49 50 protected: 51 virtual ~MIDIMessageFilter(); 52 53 private: 54 // Sends an IPC message using |channel_|. 55 void Send(IPC::Message* message); 56 57 // IPC::ChannelProxy::MessageFilter override. Called on |io_message_loop|. 58 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 59 virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE; 60 virtual void OnFilterRemoved() OVERRIDE; 61 virtual void OnChannelClosing() OVERRIDE; 62 63 // Called when the browser process has approved (or denied) access to 64 // MIDI hardware. 65 void OnSessionStarted(int client_id, 66 bool success, 67 media::MIDIPortInfoList inputs, 68 media::MIDIPortInfoList outputs); 69 70 // Called when the browser process has sent MIDI data containing one or 71 // more messages. 72 void OnDataReceived(int port, 73 const std::vector<uint8>& data, 74 double timestamp); 75 76 // From time-to-time, the browser incrementally informs us of how many bytes 77 // it has successfully sent. This is part of our throttling process to avoid 78 // sending too much data before knowing how much has already been sent. 79 void OnAcknowledgeSentData(size_t bytes_sent); 80 81 void HandleSessionStarted(int client_id, 82 bool success, 83 media::MIDIPortInfoList inputs, 84 media::MIDIPortInfoList outputs); 85 86 void HandleDataReceived(int port, 87 const std::vector<uint8>& data, 88 double timestamp); 89 90 void StartSessionOnIOThread(int client_id); 91 92 void SendMIDIDataOnIOThread(int port, 93 const std::vector<uint8>& data, 94 double timestamp); 95 96 WebKit::WebMIDIAccessorClient* GetClientFromId(int client_id); 97 98 // IPC channel for Send(); must only be accessed on |io_message_loop_|. 99 IPC::Channel* channel_; 100 101 // Message loop on which IPC calls are driven. 102 const scoped_refptr<base::MessageLoopProxy> io_message_loop_; 103 104 // Main thread's message loop. 105 scoped_refptr<base::MessageLoopProxy> main_message_loop_; 106 107 // Keeps track of all MIDI clients. 108 // We map client to "client id" used to track permission. 109 // When access has been approved, we add the input and output ports to 110 // the client, allowing it to actually receive and send MIDI data. 111 typedef std::map<WebKit::WebMIDIAccessorClient*, int> ClientsMap; 112 ClientsMap clients_; 113 114 // Dishes out client ids. 115 int next_available_id_; 116 117 size_t unacknowledged_bytes_sent_; 118 119 DISALLOW_COPY_AND_ASSIGN(MIDIMessageFilter); 120 }; 121 122 } // namespace content 123 124 #endif // CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_ 125