blob: 0d3e8a37a08511d1030bc47cda8a1195b594404b [file] [log] [blame]
Prashant Malanif07c9522017-04-11 14:54:29 -07001// Copyright 2017 The Chromium OS 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 MIDIS_CLIENT_H_
6#define MIDIS_CLIENT_H_
7
8#include <memory>
Prashant Malanif9334732017-04-26 13:06:20 -07009#include <vector>
Prashant Malanif07c9522017-04-11 14:54:29 -070010
11#include <base/files/scoped_file.h>
12#include <base/memory/weak_ptr.h>
13#include <brillo/message_loops/message_loop.h>
Prashant Malani73c1ea12017-09-06 13:28:53 -070014#include <mojo/public/cpp/bindings/binding.h>
Prashant Malanif07c9522017-04-11 14:54:29 -070015
Prashant Malanif9334732017-04-26 13:06:20 -070016#include "midis/device.h"
17#include "midis/device_tracker.h"
Prashant Malanid0c0f1a2017-07-20 15:50:08 -070018#include "midis/libmidis/clientlib.h"
Prashant Malani73c1ea12017-09-06 13:28:53 -070019#include "mojo/midis.mojom.h"
Prashant Malanif9334732017-04-26 13:06:20 -070020
Prashant Malanif07c9522017-04-11 14:54:29 -070021namespace midis {
22
Prashant Malani73c1ea12017-09-06 13:28:53 -070023class Client : public DeviceTracker::Observer, public arc::mojom::MidisServer {
Prashant Malanif07c9522017-04-11 14:54:29 -070024 public:
Prashant Malani3e40a032017-05-07 21:42:56 -070025 using ClientDeletionCallback = base::Callback<void(uint32_t)>;
Prashant Malani73c1ea12017-09-06 13:28:53 -070026 ~Client() override;
27
28 // Legacy Create() function to create a new client.
29 // Still kept here while we are in the process of transitioning to Mojo
30 // clients.
31 // TODO(pmalani): Remove once Mojo server and client interfaces are fully
32 // implemented.
Prashant Malanif9334732017-04-26 13:06:20 -070033 static std::unique_ptr<Client> Create(base::ScopedFD fd,
Prashant Malani3e40a032017-05-07 21:42:56 -070034 DeviceTracker* device_tracker,
35 uint32_t client_id,
36 ClientDeletionCallback del_callback);
Prashant Malani73c1ea12017-09-06 13:28:53 -070037
38 // Similar to the original Create() call, but for Mojo clients.
39 static std::unique_ptr<Client> CreateMojo(
40 DeviceTracker* device_tracker,
41 uint32_t client_id,
42 ClientDeletionCallback del_callback,
43 arc::mojom::MidisServerRequest request,
44 arc::mojom::MidisClientPtr client_ptr);
45
Prashant Malani3e40a032017-05-07 21:42:56 -070046 void NotifyDeviceAddedOrRemoved(struct MidisDeviceInfo* dev_info, bool added);
Prashant Malanif07c9522017-04-11 14:54:29 -070047
48 private:
Prashant Malani73c1ea12017-09-06 13:28:53 -070049 Client(base::ScopedFD fd,
50 DeviceTracker* device_tracker,
51 uint32_t client_id,
52 ClientDeletionCallback del_cb,
53 arc::mojom::MidisServerRequest request,
54 arc::mojom::MidisClientPtr client_ptr);
55
Prashant Malanif07c9522017-04-11 14:54:29 -070056 // Start monitoring the client socket fd for messages from the client.
57 bool StartMonitoring();
58 // Stop the task which was watching the client socket df.
59 void StopMonitoring();
Prashant Malanif9334732017-04-26 13:06:20 -070060 // Main function to handle all messages sent by the client.
61 // Messages will be of the following format:
62 //
63 // |<--- 4 bytes --->|<---- 4 bytes ---->|<---- payload_size bytes --->|
64 // | message type | size of payload | message payload |
Prashant Malanif07c9522017-04-11 14:54:29 -070065 void HandleClientMessages();
66
Prashant Malanif9334732017-04-26 13:06:20 -070067 // Return the list of all devices available to the client.
68 // The message format will be the same as that used by Client messages.
69 void SendDevicesList();
70
71 // Prepare the payload for devices information.
72 // Payload structure:
73 //
74 // |<-- 1 byte -->|<-- sizeof(struct MidisDeviceInfo) bytes -->|....
75 // | num entries | device1_info | device2_info
76 // |....
77 uint32_t PrepareDeviceListPayload(uint8_t* payload_buf, size_t buf_len);
78
Prashant Malani324a4e12017-05-01 17:44:17 -070079 // This function is a DeviceTracker::Observer override.
80 void OnDeviceAddedOrRemoved(const struct MidisDeviceInfo* dev_info,
81 bool added) override;
82
Prashant Malani4acb19f2017-08-09 11:35:16 -070083 void HandleCloseDeviceMessage();
84
Prashant Malani3e40a032017-05-07 21:42:56 -070085 // On receipt of a REQUEST_PORT message header, this function contacts
86 // the requisite device, obtains an FD for the relevant subdevice, and
87 // returns the FD.
88 // The FD is returned via the cmsg mechanism. The buffer will contain a
89 // struct MidisRequestPort with information regarding the port requested.
90 // The cmsg header will contain information regarding the information
91 // about the FD to be sent over.
92 //
93 // Just as the sendmsg() protocol is used by the server to send the FD, so too
94 // the client must use the recvmsg() protocol to retrieve said FD.
95 void AddClientToPort();
96
97 void TriggerClientDeletion();
98
Prashant Malanif07c9522017-04-11 14:54:29 -070099 base::ScopedFD client_fd_;
100 brillo::MessageLoop::TaskId msg_taskid_;
Prashant Malanif9334732017-04-26 13:06:20 -0700101 // The DeviceTracker can be guaranteed to exist for the lifetime of the
102 // service. As such, it is safe to maintain this pointer as a means to make
103 // updates and derive information regarding devices.
104 DeviceTracker* device_tracker_;
Prashant Malani3e40a032017-05-07 21:42:56 -0700105 uint32_t client_id_;
106 base::Callback<void(uint32_t)> del_cb_;
Prashant Malani73c1ea12017-09-06 13:28:53 -0700107
108 // Handle to the Mojo client interface. This is used to send necessary
109 // information to the clients when required.
110 arc::mojom::MidisClientPtr client_ptr_;
111 mojo::Binding<arc::mojom::MidisServer> binding_;
112
Prashant Malanif07c9522017-04-11 14:54:29 -0700113 base::WeakPtrFactory<Client> weak_factory_;
114
115 DISALLOW_COPY_AND_ASSIGN(Client);
116};
117
118} // namespace midis
119
120#endif // MIDIS_CLIENT_H_