• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 
15 #include "AndroidPipe.h"
16 #include "android_pipe_base.h"
17 
18 #include "aemu/base/Optional.h"
19 #include "aemu/base/StringFormat.h"
20 #include "aemu/base/files/MemStream.h"
21 #include "aemu/base/synchronization/Lock.h"
22 #include "android_pipe_device.h"
23 #include "android_pipe_host.h"
24 #include "host-common/GfxstreamFatalError.h"
25 #include "DeviceContextRunner.h"
26 #include "VmLock.h"
27 
28 #include <algorithm>
29 #include <memory>
30 #include <string>
31 #include <vector>
32 #include <unordered_set>
33 
34 #include <assert.h>
35 #include <string.h>
36 
37 #define DEBUG 0
38 
39 #if DEBUG >= 1
40 #include <stdio.h>
41 #define D(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
42 #else
43 #define D(...) (void)0
44 #endif
45 
46 #if DEBUG >= 2
47 #define DD(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
48 #else
49 #define DD(...) (void)0
50 #endif
51 
52 #define E(...) fprintf(stderr, "ERROR:" __VA_ARGS__), fprintf(stderr, "\n")
53 
getPipeHwFuncs(const void * hwPipe)54 static const AndroidPipeHwFuncs* getPipeHwFuncs(const void* hwPipe) {
55     return *static_cast<const AndroidPipeHwFuncs* const *>(hwPipe);
56 }
57 
58 using namespace android::base;
59 
60 using AndroidPipe = android::AndroidPipe;
61 using BaseStream = android::base::Stream;
62 using CStream = ::Stream;
63 using OptionalString = android::base::Optional<std::string>;
64 using Service = android::AndroidPipe::Service;
65 using ServiceList = std::vector<std::unique_ptr<Service>>;
66 using VmLock = android::VmLock;
67 using android::base::MemStream;
68 using android::base::StringFormat;
69 using emugl::ABORT_REASON_OTHER;
70 using emugl::FatalError;
71 
asBaseStream(CStream * stream)72 static BaseStream* asBaseStream(CStream* stream) {
73     return reinterpret_cast<BaseStream*>(stream);
74 }
75 
76 #define CHECK_VM_STATE_LOCK() (void)0
77 // b/294378605: Need to implement VM_STATE_LOCK and VM_STATE_UNLOCK for qemu. We leave this empty
78 // for now since qemu provides its own implementation of AndroidPipe.cpp.
79 #define VM_STATE_LOCK() (void)0
80 #define VM_STATE_UNLOCK() (void)0
81 
82 namespace android {
83 
84 namespace {
85 
isPipeOptional(const std::string & name)86 static bool isPipeOptional(const std::string& name) {
87     return name == "OffworldPipe";
88 }
89 
90 // Write an optional string |str| to |stream|. |str| can be null. Use
91 // readOptionalString() to read it back later.
writeOptionalString(BaseStream * stream,const char * str)92 static void writeOptionalString(BaseStream* stream, const char* str) {
93     if (str) {
94         stream->putByte(1);
95         stream->putString(str);
96     } else {
97         stream->putByte(0);
98     }
99 }
100 
101 // Read an optional string from |stream|. If the result is not constructed
102 // (i.e. equals to false), this means the original |str| parameter was null.
readOptionalString(BaseStream * stream)103 static OptionalString readOptionalString(BaseStream* stream) {
104     if (stream->getByte()) {
105         return OptionalString(stream->getString());
106     }
107     return OptionalString();
108 }
109 
110 // forward
111 Service* findServiceByName(const char* name);
112 
113 // Implementation of a special AndroidPipe class used to model the state
114 // of a pipe connection before the service name has been written to the
115 // file descriptor by the guest. The most important method is onGuestSend()
116 // which will detect when this happens.
117 class ConnectorPipe : public AndroidPipe {
118 public:
ConnectorPipe(void * hwPipe,Service * service)119     ConnectorPipe(void* hwPipe, Service* service)
120         : AndroidPipe(hwPipe, service) {
121         DD("%s: Creating new ConnectorPipe hwpipe=%p", __FUNCTION__, mHwPipe);
122     }
123 
onGuestClose(PipeCloseReason reason)124     virtual void onGuestClose(PipeCloseReason reason) override {
125         // nothing to do here
126         DD("%s: closing ConnectorPipe hwpipe=%p prematurily (reason=%d)!",
127            __func__, mHwPipe, (int)reason);
128     }
129 
onGuestPoll() const130     virtual unsigned onGuestPoll() const override {
131         // A connector always want to receive data.
132         DD("%s: polling hwpipe=%p", __FUNCTION__, mHwPipe);
133         return PIPE_POLL_OUT;
134     }
135 
onGuestRecv(AndroidPipeBuffer * buffers,int numBuffers)136     virtual int onGuestRecv(AndroidPipeBuffer* buffers,
137                             int numBuffers) override {
138         // This pipe never wants to write to the guest, so getting there
139         // is an error since PIPE_WAKE_IN is never signaled.
140         DD("%s: trying to receive data from hwpipe=%p", __FUNCTION__, mHwPipe);
141         return PIPE_ERROR_IO;
142     }
143 
144     // TECHNICAL NOTE: This function reads data from the guest until it
145     // finds a zero-terminated C-string. After that it parses it to find
146     // a registered service corresponding to one of the allowed formats
147     // (see below). In case of success, this creates a new AndroidPipe
148     // instance and calls AndroidPipeHwFuncs::resetPipe() to associate it with
149     // the current hardware-side |mHwPipe|, then *deletes* the current
150     // instance! In case of error (e.g. invalid service name, or error during
151     // initialization), PIPE_ERROR_INVAL will be returned, otherwise, the
152     // number of bytes accepted from the guest is returned.
onGuestSend(const AndroidPipeBuffer * buffers,int numBuffers,void ** newPipePtr)153     virtual int onGuestSend(const AndroidPipeBuffer* buffers,
154                             int numBuffers,
155                             void** newPipePtr) override {
156         int result = 0;
157         size_t avail = kBufferSize - mPos;
158         bool foundZero = false;
159         for (; !foundZero && avail > 0 && numBuffers > 0;
160              buffers++, numBuffers--) {
161             const uint8_t* data = buffers[0].data;
162             size_t count = std::min(avail, buffers[0].size);
163             // Read up to |count| bytes, stopping after the first zero.
164             size_t n = 0;
165             while (n < count) {
166                 uint8_t byte = data[n++];
167                 mBuffer[mPos++] = (char) byte;
168                 if (!byte) {
169                     foundZero = true;
170                     break;
171                 }
172             }
173             result += static_cast<int>(n);
174             avail -= n;
175         }
176         DD("%s: receiving %d connection bytes from hwpipe=%p", __FUNCTION__,
177            result, mHwPipe);
178 
179         if (!foundZero) {
180             if (avail == 0) {
181                 DD("%s: service name buffer full, force-closing connection",
182                    __FUNCTION__);
183                 return PIPE_ERROR_IO;
184             }
185             // Still waiting for terminating zero.
186             DD("%s: still waiting for terminating zero!", __FUNCTION__);
187             return result;
188         }
189 
190         // Acceptable formats for the connection string are:
191         //
192         //    pipe:<name>
193         //    pipe:<name>:<arguments>
194         //
195         char* pipeName;
196         char* pipeArgs;
197 
198         D("%s: connector: '%s'", __FUNCTION__, mBuffer);
199         if (memcmp(mBuffer, "pipe:", 5) != 0) {
200             // Nope, we don't handle these for now.
201             D("%s: Unknown pipe connection: '%s'", __FUNCTION__, mBuffer);
202             return PIPE_ERROR_INVAL;
203         }
204 
205         pipeName = mBuffer + 5;
206         pipeArgs = strchr(pipeName, ':');
207 
208         Service* svc = nullptr;
209 
210         // As a special case, if the service name is as:
211         //    qemud:<name>
212         //    qemud:<name>:args
213         //
214         // First look for a registered pipe service named "qemud:<name>"
215         // and if not found, fallback to "qemud" only.
216         //
217         // This is useful to support qemud services that are now served
218         // by a dedicated (and faster) pipe service, e.g. 'qemud:adb'
219         // as currently implemented by QEMU2 (and soon by QEMU1).
220         static const char kQemudPrefix[] = "qemud:";
221         const size_t kQemudPrefixSize = sizeof(kQemudPrefix) - 1U;
222 
223         if (!::strncmp(pipeName, kQemudPrefix, kQemudPrefixSize)) {
224             assert(pipeArgs == pipeName + kQemudPrefixSize - 1);
225             char* pipeArgs2 = strchr(pipeArgs + 1, ':');
226             if (pipeArgs2) {
227                 *pipeArgs2 = '\0';
228             }
229             svc = findServiceByName(pipeName);
230             if (svc) {
231                 pipeArgs = pipeArgs2;
232             } else if (pipeArgs2) {
233                 // Restore colon.
234                 *pipeArgs2 = ':';
235             }
236         }
237         if (pipeArgs) {
238             *pipeArgs++ = '\0';
239             if (!pipeArgs) {
240                 pipeArgs = NULL;
241             }
242         }
243 
244         if (!svc) {
245             svc = findServiceByName(pipeName);
246         }
247 
248         if (!svc) {
249             D("%s: Unknown server with name %s!", __FUNCTION__, pipeName);
250             return PIPE_ERROR_INVAL;
251         }
252 
253         AndroidPipe* newPipe = svc->create(mHwPipe, pipeArgs, mFlags);
254         if (!newPipe) {
255             D("%s: Initialization failed for %s pipe!", __FUNCTION__, pipeName);
256             return PIPE_ERROR_INVAL;
257         }
258 
259         // Swap your host-side pipe instance with this one weird trick!
260         D("%s: starting new pipe %p (swapping %p) for service %s",
261           __FUNCTION__,
262           newPipe,
263           mHwPipe,
264           pipeName);
265 
266         newPipe->setFlags(mFlags);
267         *newPipePtr = newPipe;
268         delete this;
269 
270         return result;
271     }
272 
onGuestWantWakeOn(int wakeFlags)273     virtual void onGuestWantWakeOn(int wakeFlags) override {
274         // nothing to do here
275         DD("%s: signaling wakeFlags=%d for hwpipe=%p", __FUNCTION__, wakeFlags,
276            mHwPipe);
277     }
278 
onSave(BaseStream * stream)279     virtual void onSave(BaseStream* stream) override {
280         DD("%s: saving connector state for hwpipe=%p", __FUNCTION__, mHwPipe);
281         stream->putBe32(mPos);
282         stream->write(mBuffer, mPos);
283     }
284 
onLoad(BaseStream * stream)285     bool onLoad(BaseStream* stream) {
286         DD("%s: loading connector state for hwpipe=%p", __FUNCTION__, mHwPipe);
287         int32_t len = stream->getBe32();
288         if (len < 0 || len > kBufferSize) {
289             D("%s: invalid length %d (expected 0 <= len <= %d)", __FUNCTION__,
290               static_cast<int>(len), kBufferSize);
291             return false;
292         }
293         mPos = (int)len;
294         int ret = (int)stream->read(mBuffer, mPos);
295         DD("%s: read %d bytes (%d expected)", __FUNCTION__, ret, mPos);
296         return (ret == mPos);
297     }
298 
299 private:
300     static constexpr int kBufferSize = 128;
301     char mBuffer[kBufferSize];
302     int mPos = 0;
303 };
304 
305 // Associated AndroidPipe::Service class for ConnectorPipe instances.
306 class ConnectorService : public Service {
307 public:
ConnectorService()308     ConnectorService() : Service("<connector>") {}
309 
create(void * hwPipe,const char * args,enum AndroidPipeFlags flags)310     AndroidPipe* create(void* hwPipe, const char* args,
311                          enum AndroidPipeFlags flags) override {
312         return new ConnectorPipe(hwPipe, this);
313     }
314 
canLoad() const315     virtual bool canLoad() const override { return true; }
316 
load(void * hwPipe,const char * args,BaseStream * stream)317     virtual AndroidPipe* load(void* hwPipe,
318                               const char* args,
319                               BaseStream* stream) override {
320         ConnectorPipe* pipe = new ConnectorPipe(hwPipe, this);
321         if (!pipe->onLoad(stream)) {
322             delete pipe;
323             return nullptr;
324         }
325         return pipe;
326     }
327 };
328 
329 // A helper class used to send signalWake() and closeFromHost() commands to
330 // the device thread, depending on the threading mode setup by the emulation
331 // engine.
332 struct PipeWakeCommand {
333     void* hwPipe;
334     int wakeFlags;
335 };
336 
337 class PipeWaker final : public DeviceContextRunner<PipeWakeCommand> {
338 public:
signalWake(void * hwPipe,int wakeFlags)339     void signalWake(void* hwPipe, int wakeFlags) {
340         queueDeviceOperation({ hwPipe, wakeFlags });
341     }
closeFromHost(void * hwPipe)342     void closeFromHost(void* hwPipe) {
343         signalWake(hwPipe, PIPE_WAKE_CLOSED);
344     }
abortPending(void * hwPipe)345     void abortPending(void* hwPipe) {
346         removeAllPendingOperations([hwPipe](const PipeWakeCommand& cmd) {
347             return cmd.hwPipe == hwPipe;
348         });
349     }
abortAllPending()350     void abortAllPending() {
351         removeAllPendingOperations([](const PipeWakeCommand& cmd) {
352             return true;
353         });
354     }
355 
getPendingFlags(void * hwPipe) const356     int getPendingFlags(void* hwPipe) const {
357         int flags = 0;
358         forEachPendingOperation([hwPipe, &flags](const PipeWakeCommand& cmd) {
359             if (cmd.hwPipe == hwPipe) {
360                 flags |= cmd.wakeFlags;
361             }
362         });
363         return flags;
364     }
365 
366 private:
performDeviceOperation(const PipeWakeCommand & wake_cmd)367     virtual void performDeviceOperation(const PipeWakeCommand& wake_cmd) {
368         void* hwPipe = wake_cmd.hwPipe;
369         int flags = wake_cmd.wakeFlags;
370 
371         // Not used when in virtio mode.
372         if (flags & PIPE_WAKE_CLOSED) {
373             getPipeHwFuncs(hwPipe)->closeFromHost(hwPipe);
374         } else {
375             getPipeHwFuncs(hwPipe)->signalWake(hwPipe, flags);
376         }
377     }
378 };
379 
380 struct Globals {
381     ServiceList services;
382     ConnectorService connectorService;
383     PipeWaker pipeWaker;
384 
385     // Searches for a service position in the |services| list and returns the
386     // index. |startPosHint| is a _hint_ and suggests where to start from.
387     // Returns the index of the service or -1 if there's no |name| service.
findServicePositionByNameandroid::__anon7fee7eb60111::Globals388     int findServicePositionByName(const char* name,
389                                   const int startPosHint = 0) const {
390         const auto searchByNameFunc =
391                 [name](const std::unique_ptr<Service>& service) {
392                     return service->name() == name;
393                 };
394 
395         // First, try to search starting from the hint position.
396         auto end = services.end();
397         auto it = std::find_if(services.begin() + startPosHint, end,
398                                searchByNameFunc);
399 
400         // If there was a hint that didn't help, continue searching from the
401         // beginning of the contatiner to check the rest of it.
402         if (it == end && startPosHint > 0) {
403             end = services.begin() + startPosHint;
404             it = std::find_if(services.begin(), end, searchByNameFunc);
405         }
406 
407         return it == end ? -1 : it - services.begin();
408     }
409 
loadServiceByNameandroid::__anon7fee7eb60111::Globals410     Service* loadServiceByName(BaseStream* stream) {
411         OptionalString serviceName = readOptionalString(stream);
412         if (!serviceName) {
413             DD("%s: no name (assuming connector state)", __FUNCTION__);
414             return &connectorService;
415         }
416         DD("%s: found [%s]", __FUNCTION__, serviceName->c_str());
417         return findServiceByName(serviceName->c_str());
418     }
419 };
420 
sGlobals()421 static Globals* sGlobals() { static Globals* g = new Globals; return g; }
422 
findServiceByName(const char * name)423 Service* findServiceByName(const char* name) {
424     const int pos = sGlobals()->findServicePositionByName(name);
425     return pos < 0 ? nullptr : sGlobals()->services[pos].get();
426 }
427 
loadPipeFromStreamCommon(BaseStream * stream,void * hwPipe,Service * service,char * pForceClose)428 AndroidPipe* loadPipeFromStreamCommon(BaseStream* stream,
429                                       void* hwPipe,
430                                       Service* service,
431                                       char* pForceClose) {
432     *pForceClose = 0;
433 
434     OptionalString args = readOptionalString(stream);
435     AndroidPipe* pipe = nullptr;
436     if (service->canLoad()) {
437         DD("%s: loading state for [%s] hwpipe=%p", __FUNCTION__,
438            service->name().c_str(), hwPipe);
439         pipe = service->load(hwPipe, args ? args->c_str() : nullptr, stream);
440         if (!pipe) {
441             *pForceClose = 1;
442         }
443     } else {
444         DD("%s: force-closing hwpipe=%p", __FUNCTION__, hwPipe);
445         *pForceClose = 1;
446     }
447 
448     const int pendingFlags = stream->getBe32();
449     if (pendingFlags && pipe && !*pForceClose) {
450         if (!hwPipe) {
451             GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
452                 << "fatal: AndroidPipe [" << pipe->name() << "] hwPipe is NULL(flags = 0x"
453                 << std::hex << unsigned(pendingFlags) << " )";
454         }
455         sGlobals()->pipeWaker.signalWake(hwPipe, pendingFlags);
456         DD("%s: singalled wake flags %d for pipe hwpipe=%p", __func__,
457            pendingFlags, hwPipe);
458     }
459 
460     return pipe;
461 }
462 
463 }  // namespace
464 
465 // static
initThreading(VmLock * vmLock)466 void AndroidPipe::initThreading(VmLock* vmLock) {
467     // TODO: Make this work in qemu with the actual goldfish pipe device.
468     // In virtio land, this won't be needed, so include trivial timer interface.
469     sGlobals()->pipeWaker.init(vmLock, {
470         // installFunc
471         [](DeviceContextRunner<PipeWakeCommand>* dcr, std::function<void()> installedFunc) {
472             (void)dcr;
473             (void)installedFunc;
474         },
475         // uninstallFunc
476         [](DeviceContextRunner<PipeWakeCommand>* dcr) {
477             (void)dcr;
478         },
479         // startWithTimeoutFunc
480         [](DeviceContextRunner<PipeWakeCommand>* dcr, uint64_t timeout) {
481             (void)dcr;
482             (void)timeout;
483         }
484     });
485 }
486 
~AndroidPipe()487 AndroidPipe::~AndroidPipe() {
488     DD("%s: for hwpipe=%p (host %p '%s')", __FUNCTION__, mHwPipe, this,
489        mService->name().c_str());
490 }
491 
492 // static
add(std::unique_ptr<Service> service)493 void AndroidPipe::Service::add(std::unique_ptr<Service> service) {
494     DD("Adding new pipe service '%s' this=%p", service->name().c_str(),
495        service.get());
496     sGlobals()->services.push_back(std::move(service));
497 }
498 
499 // static
resetAll()500 void AndroidPipe::Service::resetAll() {
501     DD("Resetting all pipe services");
502     sGlobals()->services.clear();
503 }
504 
signalWake(int wakeFlags)505 void AndroidPipe::signalWake(int wakeFlags) {
506     // i.e., pipe not using normal pipe device
507     if (mFlags) return;
508     if (!mHwPipe) {
509         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
510             << "AndroidPipe [" << name() << "]: hwPipe is NULL (flags = 0x" << std::hex
511             << unsigned(wakeFlags) << ")";
512     }
513     sGlobals()->pipeWaker.signalWake(mHwPipe, wakeFlags);
514 }
515 
closeFromHost()516 void AndroidPipe::closeFromHost() {
517     // i.e., pipe not using normal pipe device
518     if (mFlags) return;
519     if (!mHwPipe) {
520         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
521             << "AndroidPipe [" << name() << "]: hwPipe is NULL";
522     }
523     sGlobals()->pipeWaker.closeFromHost(mHwPipe);
524 }
525 
abortPendingOperation()526 void AndroidPipe::abortPendingOperation() {
527     // i.e., pipe not using normal pipe device
528     if (mFlags) return;
529 
530     if (!mHwPipe) {
531         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
532             << "AndroidPipe [" << name() << "]: hwPipe is NULL";
533     }
534     sGlobals()->pipeWaker.abortPending(mHwPipe);
535 }
536 
saveToStream(BaseStream * stream)537 void AndroidPipe::saveToStream(BaseStream* stream) {
538     // First, write service name.
539     if (mService == &sGlobals()->connectorService) {
540         // A connector pipe
541         stream->putByte(0);
542     } else {
543         // A regular service pipe.
544         stream->putByte(1);
545         stream->putString(mService->name());
546     }
547 
548     MemStream pipeStream;
549     writeOptionalString(&pipeStream, mArgs.c_str());
550 
551     // Save pipe-specific state now.
552     if (mService->canLoad()) {
553         mService->savePipe(this, &pipeStream);
554     }
555 
556     // Save the pending wake or close operations as well.
557     const int pendingFlags = sGlobals()->pipeWaker.getPendingFlags(mHwPipe);
558     pipeStream.putBe32(pendingFlags);
559 
560     pipeStream.save(stream);
561 }
562 
563 // static
loadFromStream(BaseStream * stream,void * hwPipe,char * pForceClose)564 AndroidPipe* AndroidPipe::loadFromStream(BaseStream* stream,
565                                          void* hwPipe,
566                                          char* pForceClose) {
567     Service* service = sGlobals()->loadServiceByName(stream);
568     // Always load the pipeStream, it allows us to safely skip loading streams.
569     MemStream pipeStream;
570     pipeStream.load(stream);
571 
572     if (!service) {
573         return nullptr;
574     }
575     return loadPipeFromStreamCommon(&pipeStream, hwPipe, service, pForceClose);
576 }
577 
578 // static
loadFromStreamLegacy(BaseStream * stream,void * hwPipe,uint64_t * pChannel,unsigned char * pWakes,unsigned char * pClosed,char * pForceClose)579 AndroidPipe* AndroidPipe::loadFromStreamLegacy(BaseStream* stream,
580                                                void* hwPipe,
581                                                uint64_t* pChannel,
582                                                unsigned char* pWakes,
583                                                unsigned char* pClosed,
584                                                char* pForceClose) {
585     Service* service = sGlobals()->loadServiceByName(stream);
586     // Always load the pipeStream, it allows us to safely skip loading streams.
587     MemStream pipeStream;
588     pipeStream.load(stream);
589 
590     if (!service) {
591         return nullptr;
592     }
593     *pChannel = pipeStream.getBe64();
594     *pWakes = pipeStream.getByte();
595     *pClosed = pipeStream.getByte();
596 
597     return loadPipeFromStreamCommon(&pipeStream, hwPipe, service, pForceClose);
598 }
599 
600 }  // namespace android
601 
602 // API for the virtual device.
603 
android_pipe_reset_services()604 void android_pipe_reset_services() {
605     AndroidPipe::Service::resetAll();
606 }
607 
android_pipe_guest_open(void * hwpipe)608 void* android_pipe_guest_open(void* hwpipe) {
609     CHECK_VM_STATE_LOCK();
610     DD("%s: Creating new connector pipe for hwpipe=%p", __FUNCTION__, hwpipe);
611     return android::sGlobals()->connectorService.create(hwpipe, nullptr, (AndroidPipeFlags)0);
612 }
613 
android_pipe_guest_open_with_flags(void * hwpipe,uint32_t flags)614 void* android_pipe_guest_open_with_flags(void* hwpipe, uint32_t flags) {
615     CHECK_VM_STATE_LOCK();
616     DD("%s: Creating new connector pipe for hwpipe=%p", __FUNCTION__, hwpipe);
617     auto pipe =
618         android::sGlobals()->connectorService.create(hwpipe, nullptr, (AndroidPipeFlags)flags);
619     pipe->setFlags((AndroidPipeFlags)flags);
620     return pipe;
621 }
622 
android_pipe_guest_close(void * internalPipe,PipeCloseReason reason)623 void android_pipe_guest_close(void* internalPipe, PipeCloseReason reason) {
624     CHECK_VM_STATE_LOCK();
625     auto pipe = static_cast<android::AndroidPipe*>(internalPipe);
626     if (pipe) {
627         D("%s: host=%p [%s] reason=%d", __FUNCTION__, pipe, pipe->name(),
628             (int)reason);
629         pipe->abortPendingOperation();
630         pipe->onGuestClose(reason);
631     }
632 }
633 
634 template <class Func>
forEachServiceToStream(CStream * stream,Func && func)635 static void forEachServiceToStream(CStream* stream, Func&& func) {
636     BaseStream* const bs = asBaseStream(stream);
637     bs->putBe16(android::sGlobals()->services.size());
638     for (const auto& service : android::sGlobals()->services) {
639         bs->putString(service->name());
640 
641         // Write to the pipeStream first so that we know the length and can
642         // enable skipping loading specific pipes on load, see isPipeOptional.
643         MemStream pipeStream;
644         func(service.get(), &pipeStream);
645         pipeStream.save(bs);
646     }
647 }
648 
649 template <class Func>
forEachServiceFromStream(CStream * stream,Func && func)650 static void forEachServiceFromStream(CStream* stream, Func&& func) {
651     const auto& services = android::sGlobals()->services;
652     BaseStream* const bs = asBaseStream(stream);
653     const int count = bs->getBe16();
654     int servicePos = -1;
655     std::unordered_set<Service*> missingServices;
656     for (const auto& service : services) {
657         missingServices.insert(service.get());
658     }
659     for (int i = 0; i < count; ++i) {
660         const auto name = bs->getString();
661         servicePos = android::sGlobals()->findServicePositionByName(
662                                  name.c_str(), servicePos + 1);
663 
664         // Always load the pipeStream, so that if the pipe is missing it does
665         // not corrupt the next pipe.
666         MemStream pipeStream;
667         pipeStream.load(bs);
668 
669         if (servicePos >= 0) {
670             const auto& service = services[servicePos];
671             func(service.get(), &pipeStream);
672             missingServices.erase(service.get());
673         } else if (android::isPipeOptional(name)) {
674             D("%s: Skipping optional pipe %s\n", __FUNCTION__, name.c_str());
675         } else {
676             assert(false && "Service for snapshot pipe does not exist");
677             E("%s: Could not load pipe %s, service does not exist\n",
678               __FUNCTION__, name.c_str());
679         }
680     }
681 
682     // Now call the same function for all services that weren't in the snapshot.
683     // Pass |nullptr| instead of the stream pointer to make sure they know
684     // that while we're loading from a snapshot these services aren't part
685     // of it.
686     for (const auto service : missingServices) {
687         func(service, nullptr);
688     }
689 }
690 
android_pipe_guest_pre_load(CStream * stream)691 void android_pipe_guest_pre_load(CStream* stream) {
692     CHECK_VM_STATE_LOCK();
693     // We may not call qemu_set_irq() until the snapshot is loaded.
694     android::sGlobals()->pipeWaker.abortAllPending();
695     android::sGlobals()->pipeWaker.setContextRunMode(
696                 android::ContextRunMode::DeferAlways);
697     forEachServiceFromStream(stream, [](Service* service, BaseStream* bs) {
698         if (service->canLoad()) {
699             service->preLoad(bs);
700         }
701     });
702 }
703 
android_pipe_guest_post_load(CStream * stream)704 void android_pipe_guest_post_load(CStream* stream) {
705     CHECK_VM_STATE_LOCK();
706     forEachServiceFromStream(stream, [](Service* service, BaseStream* bs) {
707         if (service->canLoad()) {
708             service->postLoad(bs);
709         }
710     });
711     // Restore the regular handling of pipe interrupt requests.
712     android::sGlobals()->pipeWaker.setContextRunMode(
713                 android::ContextRunMode::DeferIfNotLocked);
714 }
715 
android_pipe_guest_pre_save(CStream * stream)716 void android_pipe_guest_pre_save(CStream* stream) {
717     CHECK_VM_STATE_LOCK();
718     forEachServiceToStream(stream, [](Service* service, BaseStream* bs) {
719         if (service->canLoad()) {
720             service->preSave(bs);
721         }
722     });
723 }
724 
android_pipe_guest_post_save(CStream * stream)725 void android_pipe_guest_post_save(CStream* stream) {
726     CHECK_VM_STATE_LOCK();
727     forEachServiceToStream(stream, [](Service* service, BaseStream* bs) {
728         if (service->canLoad()) {
729             service->postSave(bs);
730         }
731     });
732 }
733 
android_pipe_guest_save(void * internalPipe,CStream * stream)734 void android_pipe_guest_save(void* internalPipe, CStream* stream) {
735     CHECK_VM_STATE_LOCK();
736     auto pipe = static_cast<android::AndroidPipe*>(internalPipe);
737     DD("%s: host=%p [%s]", __FUNCTION__, pipe, pipe->name());
738     pipe->saveToStream(asBaseStream(stream));
739 }
740 
android_pipe_guest_load(CStream * stream,void * hwPipe,char * pForceClose)741 void* android_pipe_guest_load(CStream* stream,
742                               void* hwPipe,
743                               char* pForceClose) {
744     CHECK_VM_STATE_LOCK();
745     DD("%s: hwpipe=%p", __FUNCTION__, hwPipe);
746     return AndroidPipe::loadFromStream(asBaseStream(stream), hwPipe,
747                                        pForceClose);
748 }
749 
android_pipe_guest_load_legacy(CStream * stream,void * hwPipe,uint64_t * pChannel,unsigned char * pWakes,unsigned char * pClosed,char * pForceClose)750 void* android_pipe_guest_load_legacy(CStream* stream,
751                                      void* hwPipe,
752                                      uint64_t* pChannel,
753                                      unsigned char* pWakes,
754                                      unsigned char* pClosed,
755                                      char* pForceClose) {
756     CHECK_VM_STATE_LOCK();
757     DD("%s: hwpipe=%p", __FUNCTION__, hwPipe);
758     return android::AndroidPipe::loadFromStreamLegacy(asBaseStream(stream),
759                                                       hwPipe, pChannel, pWakes,
760                                                       pClosed, pForceClose);
761 }
762 
android_pipe_guest_poll(void * internalPipe)763 unsigned android_pipe_guest_poll(void* internalPipe) {
764     CHECK_VM_STATE_LOCK();
765     auto pipe = static_cast<AndroidPipe*>(internalPipe);
766     DD("%s: host=%p [%s]", __FUNCTION__, pipe, pipe->name());
767     return pipe->onGuestPoll();
768 }
769 
android_pipe_guest_recv(void * internalPipe,AndroidPipeBuffer * buffers,int numBuffers)770 int android_pipe_guest_recv(void* internalPipe,
771                             AndroidPipeBuffer* buffers,
772                             int numBuffers) {
773     CHECK_VM_STATE_LOCK();
774     auto pipe = static_cast<AndroidPipe*>(internalPipe);
775     // Note that pipe may be deleted during this call, so it's not safe to
776     // access pipe after this point.
777     return pipe->onGuestRecv(buffers, numBuffers);
778 }
779 
android_pipe_wait_guest_recv(void * internalPipe)780 void android_pipe_wait_guest_recv(void* internalPipe) {
781     CHECK_VM_STATE_LOCK();
782     auto pipe = static_cast<AndroidPipe*>(internalPipe);
783     VM_STATE_UNLOCK();
784     pipe->waitGuestRecv();
785     VM_STATE_LOCK();
786 }
787 
android_pipe_guest_send(void ** internalPipe,const AndroidPipeBuffer * buffers,int numBuffers)788 int android_pipe_guest_send(void** internalPipe,
789                             const AndroidPipeBuffer* buffers,
790                             int numBuffers) {
791     CHECK_VM_STATE_LOCK();
792     auto pipe = static_cast<AndroidPipe*>(*internalPipe);
793     // Note that pipe may be deleted during this call, so it's not safe to
794     // access pipe after this point.
795     return pipe->onGuestSend(buffers, numBuffers, internalPipe);
796 }
797 
android_pipe_wait_guest_send(void * internalPipe)798 void android_pipe_wait_guest_send(void* internalPipe) {
799     CHECK_VM_STATE_LOCK();
800     auto pipe = static_cast<AndroidPipe*>(internalPipe);
801     VM_STATE_UNLOCK();
802     pipe->waitGuestSend();
803     VM_STATE_LOCK();
804 }
805 
android_pipe_guest_wake_on(void * internalPipe,unsigned wakes)806 void android_pipe_guest_wake_on(void* internalPipe, unsigned wakes) {
807     CHECK_VM_STATE_LOCK();
808     auto pipe = static_cast<AndroidPipe*>(internalPipe);
809     pipe->onGuestWantWakeOn(wakes);
810 }
811 
812 // API implemented by the virtual device.
android_pipe_host_close(void * hwpipe)813 void android_pipe_host_close(void* hwpipe) {
814     auto pipe = static_cast<android::AndroidPipe*>(hwpipe);
815     D("%s: host=%p [%s]", __FUNCTION__, pipe, pipe->name());
816     android::sGlobals()->pipeWaker.closeFromHost(pipe);
817 }
818 
android_pipe_host_signal_wake(void * hwpipe,unsigned flags)819 void android_pipe_host_signal_wake(void* hwpipe, unsigned flags) {
820     android::sGlobals()->pipeWaker.signalWake(hwpipe, flags);
821 }
822 
823 // Not used when in virtio mode.
android_pipe_get_id(void * hwpipe)824 int android_pipe_get_id(void* hwpipe) {
825     return getPipeHwFuncs(hwpipe)->getPipeId(hwpipe);
826 }
827 
828 static std::vector<std::pair<void*(*)(int), const char*>> lookup_by_id_callbacks;
829 
android_pipe_append_lookup_by_id_callback(void * (* cb)(int),const char * tag)830 void android_pipe_append_lookup_by_id_callback(void*(*cb)(int), const char* tag) {
831     lookup_by_id_callbacks.push_back({cb, tag});
832 }
833 
android_pipe_lookup_by_id(const int id)834 void* android_pipe_lookup_by_id(const int id) {
835     void* hwPipeFound = nullptr;
836     const char* tagFound = "(null)";
837 
838     for (const auto &cb : lookup_by_id_callbacks) {
839         void* hwPipe = (*cb.first)(id);
840         if (hwPipe) {
841             if (hwPipeFound) {
842                 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
843                     << "Pipe id (" << id << ") is not unique, at least two pipes are found: `"
844                     << tagFound << "` and `" << cb.second << "`";
845             } else {
846                 hwPipeFound = hwPipe;
847                 tagFound = cb.second;
848             }
849         }
850     }
851 
852     return hwPipeFound;
853 }
854