• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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