1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15
16 #include <stddef.h>
17
18 #include <array>
19 #include <cstdint>
20 #include <functional>
21 #include <list>
22 #include <memory>
23 #include <mutex>
24 #include <string>
25 #include <unordered_map>
26 #include <utility>
27 #include <vector>
28
29 #include "aemu/base/Optional.h"
30 #include "aemu/base/files/Stream.h"
31 #include "aemu/base/logging/Log.h"
32 #include "aemu/base/synchronization/Lock.h"
33 #include "host-common/AndroidPipe.h"
34 #include "host-common/android_pipe_common.h"
35
36 // This is a utility class that can help implement message-based remote calls
37 // between the host and guest, with optional out-of-band responses.
38 //
39 // Usage:
40 // 1. Inherit AndroidMessagePipe, and implement OnMessage to receive callbacks
41 // when messages are received.
42 // 2. Call Send(data) to send a response to the client.
43 //
44 // VERY IMPORTANT: this function runs on a QEMU's CPU thread while BQL is
45 // locked. This means the OnMessage must be quick, if any complex operation must
46 // be done do it on another thread and call send(data) from that thread.
47 //
48 // 3. Register the service
49 // void registerMyXYZService() {
50 // android::AndroidPipe::Service::add(new
51 // android::AndroidAsyncMessagePipe::Service<YourPipe>("MyXYZService");
52 // }
53 //
54 // AndroidAsyncMessagePipe implements a simple packet-based protocol on top of
55 // qemu pipe service. The length of each packet is encoded as a little-endian
56 // uint32 immediately before the message:
57 //
58 // <uint32 length> <length bytes of data>
59 //
60 // (Little-endian is for historical reasons for compatibility with
61 // AndroidMessagePipe-based pipes)
62 //
63 //
64 // To enable async operations, AndroidAsyncMessagePipe allows holding a
65 // reference to a pipe using AsyncMessagePipeHandle. To get a handle, call
66 // AndroidAsyncMessagePipe::getHandle().
67 //
68 // To get a pipe instance back again with a handle, call
69 // AndroidAsyncMessagePipe::Service<PipeType>>::getPipe(handle), which will
70 // return the pipe if it is valid, or nullopt_t if it has already been
71 // destroyed. This is returned in the form of a PipeRef, which holds a lock
72 // on the pipe until it goes out of scope.
73 //
74 // AsyncMessagePipeHandle has the unique property that it also persists snapshot
75 // save and restore, so it can be used to store persistent data across
76 // snapshot sessions.
77
78 namespace android {
79
80 struct AsyncMessagePipeHandle {
81 int id = -1;
82
isValidAsyncMessagePipeHandle83 bool isValid() const { return id >= 0; }
84 bool operator<(const AsyncMessagePipeHandle& other) const {
85 return id < other.id;
86 }
87
88 bool operator==(const AsyncMessagePipeHandle& other) const {
89 return id == other.id;
90 }
91 };
92
93 class AndroidAsyncMessagePipe : public AndroidPipe {
94 public:
95 struct PipeArgs {
96 AsyncMessagePipeHandle handle;
97 void* hwPipe;
98 const char* args;
99 std::function<void(AsyncMessagePipeHandle)> deleter;
100 };
101
102 //
103 // Pipe Service
104 //
105
106 template <typename PipeType>
107 class Service : public AndroidPipe::Service {
108 public:
Service(const char * serviceName)109 Service(const char* serviceName) : AndroidPipe::Service(serviceName) {}
110
canLoad()111 bool canLoad() const override { return true; }
112
load(void * hwPipe,const char * args,base::Stream * stream)113 virtual AndroidPipe* load(void* hwPipe,
114 const char* args,
115 base::Stream* stream) final {
116 AsyncMessagePipeHandle handle;
117 handle.id = static_cast<int>(stream->getBe32());
118
119 base::AutoLock lock(mLock);
120 return createPipeUnderLock(handle, hwPipe, args, stream);
121 }
122
create(void * hwPipe,const char * args,enum AndroidPipeFlags flags)123 virtual AndroidPipe* create(void* hwPipe, const char* args,
124 enum AndroidPipeFlags flags) final {
125 base::AutoLock lock(mLock);
126 AsyncMessagePipeHandle handle = nextPipeHandle();
127 return createPipeUnderLock(handle, hwPipe, args, nullptr);
128 }
129
130 // Called once per whole vm save/load operation.
preSave(base::Stream * stream)131 virtual void preSave(base::Stream* stream) override {
132 stream->putBe32(mNextId);
133 }
134
preLoad(base::Stream * stream)135 virtual void preLoad(base::Stream* stream) override {
136 mNextId = stream->getBe32();
137 }
138
savePipe(AndroidPipe * pipe,android::base::Stream * stream)139 virtual void savePipe(AndroidPipe* pipe,
140 android::base::Stream* stream) override {
141 auto derivedPipe = static_cast<PipeType*>(pipe);
142 stream->putBe32(static_cast<uint32_t>(derivedPipe->getHandle().id));
143 AndroidPipe::Service::savePipe(pipe, stream);
144 }
145
146 struct PipeRef {
147 PipeType* const pipe;
148 base::AutoLock lock;
149 };
150
getPipe(AsyncMessagePipeHandle handle)151 base::Optional<PipeRef> getPipe(AsyncMessagePipeHandle handle) {
152 base::AutoLock lock(mLock);
153 const auto it = mPipes.find(handle.id);
154 if (it == mPipes.end()) {
155 dprint("getPipe could not find pipe id %d", handle.id);
156 return {};
157 }
158
159 return PipeRef{it->second.get(), std::move(lock)};
160 }
161
162 private:
createPipeUnderLock(AsyncMessagePipeHandle handle,void * hwPipe,const char * args,base::Stream * stream)163 AndroidPipe* createPipeUnderLock(AsyncMessagePipeHandle handle,
164 void* hwPipe,
165 const char* args,
166 base::Stream* stream) {
167 PipeArgs pipeArgs = {handle, hwPipe, args,
168 std::bind(&Service::destroyPipe, this,
169 std::placeholders::_1)};
170 std::unique_ptr<PipeType> pipe(
171 new PipeType(this, std::move(pipeArgs)));
172 if (stream) {
173 pipe->onLoad(stream);
174 }
175 AndroidPipe* pipePtr = pipe.get();
176 mPipes[handle.id] = std::move(pipe);
177 return pipePtr;
178 }
179
destroyPipe(AsyncMessagePipeHandle handle)180 void destroyPipe(AsyncMessagePipeHandle handle) {
181 // To avoid destructing under a lock, move it out of the map first.
182 std::unique_ptr<PipeType> pipe;
183 {
184 base::AutoLock lock(mLock);
185 auto it = mPipes.find(handle.id);
186 if (it != mPipes.end()) {
187 pipe = std::move(it->second);
188 mPipes.erase(it);
189 } else {
190 dprint("Could not find pipe id %d, pipe already destroyed?", handle.id);
191 }
192 }
193 }
194
nextPipeHandle()195 AsyncMessagePipeHandle nextPipeHandle() {
196 AsyncMessagePipeHandle handle;
197 handle.id = mNextId++;
198 return handle;
199 }
200
201 base::Lock mLock;
202 int mNextId = 0;
203 std::unordered_map<int, std::unique_ptr<PipeType>> mPipes;
204 };
205
206 AndroidAsyncMessagePipe(AndroidPipe::Service* service, PipeArgs&& args);
207 virtual ~AndroidAsyncMessagePipe();
208
209 void send(std::vector<uint8_t>&& data);
210 void send(const std::vector<uint8_t>& data);
211 virtual void onMessage(const std::vector<uint8_t>& data) = 0;
212
213 // Waits for any pending messages to be sent and then calls closeFromHost().
214 void queueCloseFromHost();
215
216 void onSave(base::Stream* stream) override;
217 virtual void onLoad(base::Stream* stream);
218
getHandle()219 AsyncMessagePipeHandle getHandle() { return mHandle; }
220
221 private:
222 bool allowRead() const;
223
224 int readBuffers(const AndroidPipeBuffer* buffers, int numBuffers);
225 int writeBuffers(AndroidPipeBuffer* buffers, int numBuffers);
226
onGuestClose(PipeCloseReason reason)227 void onGuestClose(PipeCloseReason reason) final { mDeleter(mHandle); }
228 unsigned onGuestPoll() const final;
onGuestWantWakeOn(int flags)229 void onGuestWantWakeOn(int flags) final {}
230
231 // Rename onGuestRecv/onGuestSend to be in the context of the host.
onGuestRecv(AndroidPipeBuffer * buffers,int numBuffers)232 int onGuestRecv(AndroidPipeBuffer* buffers, int numBuffers) final {
233 return writeBuffers(buffers, numBuffers);
234 }
235
onGuestSend(const AndroidPipeBuffer * buffers,int numBuffers,void ** newPipePtr)236 int onGuestSend(const AndroidPipeBuffer* buffers, int numBuffers,
237 void** newPipePtr) final {
238 return readBuffers(buffers, numBuffers);
239 }
240
241 struct OutgoingPacket {
242 size_t offset = 0;
243 std::vector<uint8_t> data;
244
245 OutgoingPacket(std::vector<uint8_t>&& data);
246 explicit OutgoingPacket(base::Stream* stream);
247
lengthOutgoingPacket248 size_t length() const { return sizeof(uint32_t) + data.size(); }
249 bool complete() const;
250
251 // Copy the packet contents to the AndroidPipeBuffer, updating
252 // writeOffset based on how much was written.
253 void copyToBuffer(AndroidPipeBuffer& buffer, size_t* writeOffset);
254
255 // Serialize to a stream.
256 void serialize(base::Stream* stream) const;
257 };
258
259 struct IncomingPacket {
260 size_t headerBytesRead = 0;
261 uint32_t messageLength = 0;
262 std::vector<uint8_t> data;
263
264 IncomingPacket() = default;
265 explicit IncomingPacket(base::Stream* stream);
266
267 bool lengthKnown() const;
268 base::Optional<size_t> bytesRemaining() const;
269 bool complete() const;
270
271 // Read the packet data from an AndroidPipeBuffer, updating the
272 // readOffset based on how much was written.
273 //
274 // Returns the number of bytes read.
275 size_t copyFromBuffer(const AndroidPipeBuffer& buffer,
276 size_t* readOffset);
277
278 // Serialize to a stream.
279 void serialize(base::Stream* stream) const;
280 };
281
282 struct PipeState {
283 mutable std::recursive_mutex mMutex;
284 bool mDeleted = false;
285 };
286 std::shared_ptr<PipeState> mState = std::make_shared<PipeState>();
287 const AsyncMessagePipeHandle mHandle;
288 const std::function<void(AsyncMessagePipeHandle)> mDeleter;
289 bool mCloseQueued = false;
290
291 base::Optional<IncomingPacket> mIncomingPacket;
292 std::list<OutgoingPacket> mOutgoingPackets;
293 };
294
295 typedef std::function<void(std::vector<uint8_t>&&)> PipeSendFunction;
296 typedef std::function<void(const std::vector<uint8_t>&,
297 const PipeSendFunction& func)>
298 OnMessageCallbackFunction;
299
300 // Register a AndroidAsyncMessagePipe service. Takes ownership of the pointer,
301 // and will delete on cleanup.
registerAsyncMessagePipeService(T service)302 template <typename T> void registerAsyncMessagePipeService(T service) {
303 android::AndroidPipe::Service::add(std::move(service));
304 }
305
306 // Helper to register a message pipe service with a lambda as an onMessage
307 // handler.
308 //
309 // Takes a callback with this signature:
310 // void onMessageCallback(const std::vector<uint8_t>& data,
311 // sendFunction(std::vector<uint8_t>&& response));
312 //
313 // When ready to send a callback, simply invoke sendFunction, which works from
314 // within the onMessageCallback or from any other thread.
315 void registerAsyncMessagePipeService(
316 const char* serviceName,
317 OnMessageCallbackFunction onMessageCallback);
318
319 } // namespace android
320