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