// Copyright (C) 2018 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include "base/Result.h" #include "base/Stream.h" #include "host-common/android_pipe_base.h" #include #include #include #include #include #include #include // Fake pipe driver and device for testing goldfish pipe on host without // running a VM. namespace android { class HostGoldfishPipeDevice { public: static constexpr int kNoFd = -1; using ReadResult = android::base::Result, int>; using WriteResult = android::base::Result; HostGoldfishPipeDevice(); ~HostGoldfishPipeDevice(); int getErrno() const; // Opens/closes pipe services. int connect(const char* name); void close(int fd); // Read/write for a particular pipe, along with C++ versions. ssize_t read(int fd, void* buffer, size_t len); ssize_t write(int fd, const void* buffer, size_t len); ReadResult read(int fd, size_t maxLength); WriteResult write(int fd, const std::vector& data); unsigned poll(int fd) const; // Sets a callback that will be invoked when the pipe is signaled by the // host, accepts an "int wakes" parameter that matches contains PIPE_WAKE_* // flags. void setWakeCallback(int fd, std::function callback); // Gets the host side pipe object corresponding to hwpipe. // Not persistent across snapshot save/load. void* getHostPipe(int fd) const; // Saves/loads the entire set of pipes including pre/post save/load. void saveSnapshot(base::Stream* stream); void loadSnapshot(base::Stream* stream); // Save/load the device, but only for a particular hwpipe. void saveSnapshot(base::Stream* stream, int fd); int loadSnapshotSinglePipe(base::Stream* stream); // Closes all pipes and resets to initial state. void clear(); static HostGoldfishPipeDevice* get(); private: void initialize(); struct InternalPipe {}; struct HostHwPipe { explicit HostHwPipe(int fd); ~HostHwPipe(); int getFd() const { return mFd; } static std::unique_ptr create(int fd); private: static const AndroidPipeHwFuncs vtbl; const AndroidPipeHwFuncs* const vtblPtr; int mFd; }; friend HostHwPipe; struct FdInfo { std::unique_ptr hwPipe; InternalPipe* hostPipe = nullptr; std::function wakeCallback = [](int){}; }; void clearLocked(); FdInfo* lookupFdInfo(int fd); const FdInfo* lookupFdInfo(int fd) const; HostHwPipe* associatePipes(std::unique_ptr hwPipe, InternalPipe* hostPipe); bool eraseFdInfo(int fd); ssize_t writeInternal(InternalPipe** pipe, const void* buffer, size_t len); void setErrno(ssize_t res); // Wake a hwpipe. void signalWake(int fd, int wakes); // Callbacks for AndroidPipeHwFuncs. static void closeFromHostCallback(void* hwpipe); static void signalWakeCallback(void* hwpipe, unsigned wakes); static int getPipeIdCallback(void* hwpipe); bool mInitialized = false; int mFdGenerator = 0; int mErrno = 0; std::unordered_map mPipeToHwPipe; std::unordered_map mFdInfo; }; // Initializes a global pipe instance for the current process. HostGoldfishPipeDevice* getHostPipeInstance(); } // namespace android