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