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 "aemu/base/Result.h" 17 #include "aemu/base/files/Stream.h" 18 #include "host-common/android_pipe_base.h" 19 20 #include <cstdint> 21 #include <functional> 22 #include <unordered_map> 23 #include <unordered_set> 24 #include <vector> 25 #include <memory> 26 27 #include <sys/types.h> 28 29 // Fake pipe driver and device for testing goldfish pipe on host without 30 // running a VM. 31 namespace android { 32 33 class HostGoldfishPipeDevice { 34 public: 35 static constexpr int kNoFd = -1; 36 37 using ReadResult = android::base::Result<std::vector<uint8_t>, int>; 38 using WriteResult = android::base::Result<ssize_t, int>; 39 40 HostGoldfishPipeDevice(); 41 ~HostGoldfishPipeDevice(); 42 43 int getErrno() const; 44 45 // Opens/closes pipe services. 46 int connect(const char* name); 47 void close(int fd); 48 49 // Read/write for a particular pipe, along with C++ versions. 50 ssize_t read(int fd, void* buffer, size_t len); 51 ssize_t write(int fd, const void* buffer, size_t len); 52 ReadResult read(int fd, size_t maxLength); 53 WriteResult write(int fd, const std::vector<uint8_t>& data); 54 unsigned poll(int fd) const; 55 56 // Sets a callback that will be invoked when the pipe is signaled by the 57 // host, accepts an "int wakes" parameter that matches contains PIPE_WAKE_* 58 // flags. 59 void setWakeCallback(int fd, std::function<void(int)> callback); 60 61 // Gets the host side pipe object corresponding to hwpipe. 62 // Not persistent across snapshot save/load. 63 void* getHostPipe(int fd) const; 64 65 // Saves/loads the entire set of pipes including pre/post save/load. 66 void saveSnapshot(base::Stream* stream); 67 void loadSnapshot(base::Stream* stream); 68 69 // Save/load the device, but only for a particular hwpipe. 70 void saveSnapshot(base::Stream* stream, int fd); 71 int loadSnapshotSinglePipe(base::Stream* stream); 72 73 // Closes all pipes and resets to initial state. 74 void clear(); 75 76 static HostGoldfishPipeDevice* get(); 77 78 private: 79 void initialize(); 80 81 struct InternalPipe {}; 82 83 struct HostHwPipe { 84 explicit HostHwPipe(int fd); 85 ~HostHwPipe(); 86 getFdHostHwPipe87 int getFd() const { return mFd; } 88 89 static std::unique_ptr<HostHwPipe> create(int fd); 90 91 private: 92 static const AndroidPipeHwFuncs vtbl; 93 94 const AndroidPipeHwFuncs* const vtblPtr; 95 int mFd; 96 }; 97 98 friend HostHwPipe; 99 100 struct FdInfo { 101 std::unique_ptr<HostHwPipe> hwPipe; 102 InternalPipe* hostPipe = nullptr; 103 std::function<void(int)> wakeCallback = [](int){}; 104 }; 105 106 void clearLocked(); 107 108 FdInfo* lookupFdInfo(int fd); 109 const FdInfo* lookupFdInfo(int fd) const; 110 111 HostHwPipe* associatePipes(std::unique_ptr<HostHwPipe> hwPipe, 112 InternalPipe* hostPipe); 113 bool eraseFdInfo(int fd); 114 115 ssize_t writeInternal(InternalPipe** pipe, const void* buffer, size_t len); 116 117 void setErrno(ssize_t res); 118 119 // Wake a hwpipe. 120 void signalWake(int fd, int wakes); 121 122 // Callbacks for AndroidPipeHwFuncs. 123 static void closeFromHostCallback(void* hwpipe); 124 static void signalWakeCallback(void* hwpipe, unsigned wakes); 125 static int getPipeIdCallback(void* hwpipe); 126 127 bool mInitialized = false; 128 int mFdGenerator = 0; 129 int mErrno = 0; 130 131 std::unordered_map<InternalPipe*, HostHwPipe*> mPipeToHwPipe; 132 std::unordered_map<int, FdInfo> mFdInfo; 133 }; 134 135 // Initializes a global pipe instance for the current process. 136 HostGoldfishPipeDevice* getHostPipeInstance(); 137 138 } // namespace android 139 140