xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderRpcTestCommon.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <BinderRpcTestClientInfo.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <BinderRpcTestServerConfig.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <BinderRpcTestServerInfo.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <BnBinderRpcCallback.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <BnBinderRpcSession.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <BnBinderRpcTest.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <binder/Binder.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <binder/BpBinder.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcServer.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcSession.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcThreads.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTransport.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTransportRaw.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <cinttypes>
36*38e8c45fSAndroid Build Coastguard Worker #include <string>
37*38e8c45fSAndroid Build Coastguard Worker #include <vector>
38*38e8c45fSAndroid Build Coastguard Worker 
39*38e8c45fSAndroid Build Coastguard Worker #ifdef __ANDROID__
40*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
41*38e8c45fSAndroid Build Coastguard Worker #endif
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker #ifndef __TRUSTY__
44*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_auto_utils.h>
45*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_libbinder.h>
46*38e8c45fSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
47*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTlsTestUtils.h>
48*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTlsUtils.h>
49*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTransportTls.h>
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker #include <signal.h>
52*38e8c45fSAndroid Build Coastguard Worker 
53*38e8c45fSAndroid Build Coastguard Worker #include "../OS.h"               // for testing UnixBootstrap clients
54*38e8c45fSAndroid Build Coastguard Worker #include "../RpcSocketAddress.h" // for testing preconnected clients
55*38e8c45fSAndroid Build Coastguard Worker #include "../vm_sockets.h"       // for VMADDR_*
56*38e8c45fSAndroid Build Coastguard Worker #endif                           // __TRUSTY__
57*38e8c45fSAndroid Build Coastguard Worker 
58*38e8c45fSAndroid Build Coastguard Worker #include "../BuildFlags.h"
59*38e8c45fSAndroid Build Coastguard Worker #include "../FdTrigger.h"
60*38e8c45fSAndroid Build Coastguard Worker #include "../FdUtils.h"
61*38e8c45fSAndroid Build Coastguard Worker #include "../RpcState.h" // for debugging
62*38e8c45fSAndroid Build Coastguard Worker #include "FileUtils.h"
63*38e8c45fSAndroid Build Coastguard Worker #include "utils/Errors.h"
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker namespace android {
66*38e8c45fSAndroid Build Coastguard Worker 
67*38e8c45fSAndroid Build Coastguard Worker #ifdef BINDER_NO_KERNEL_IPC_TESTING
68*38e8c45fSAndroid Build Coastguard Worker constexpr bool kEnableKernelIpcTesting = false;
69*38e8c45fSAndroid Build Coastguard Worker #else
70*38e8c45fSAndroid Build Coastguard Worker constexpr bool kEnableKernelIpcTesting = true;
71*38e8c45fSAndroid Build Coastguard Worker #endif
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker constexpr char kLocalInetAddress[] = "127.0.0.1";
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker enum class RpcSecurity { RAW, TLS };
76*38e8c45fSAndroid Build Coastguard Worker 
RpcSecurityValues()77*38e8c45fSAndroid Build Coastguard Worker static inline std::vector<RpcSecurity> RpcSecurityValues() {
78*38e8c45fSAndroid Build Coastguard Worker     return {RpcSecurity::RAW, RpcSecurity::TLS};
79*38e8c45fSAndroid Build Coastguard Worker }
80*38e8c45fSAndroid Build Coastguard Worker 
noKernelValues()81*38e8c45fSAndroid Build Coastguard Worker static inline std::vector<bool> noKernelValues() {
82*38e8c45fSAndroid Build Coastguard Worker     std::vector<bool> values = {true};
83*38e8c45fSAndroid Build Coastguard Worker     if (kEnableKernelIpcTesting) {
84*38e8c45fSAndroid Build Coastguard Worker         values.push_back(false);
85*38e8c45fSAndroid Build Coastguard Worker     }
86*38e8c45fSAndroid Build Coastguard Worker     return values;
87*38e8c45fSAndroid Build Coastguard Worker }
88*38e8c45fSAndroid Build Coastguard Worker 
hasExperimentalRpc()89*38e8c45fSAndroid Build Coastguard Worker static inline bool hasExperimentalRpc() {
90*38e8c45fSAndroid Build Coastguard Worker #ifdef BINDER_RPC_TO_TRUSTY_TEST
91*38e8c45fSAndroid Build Coastguard Worker     // Trusty services do not support the experimental version,
92*38e8c45fSAndroid Build Coastguard Worker     // so that we can update the prebuilts separately.
93*38e8c45fSAndroid Build Coastguard Worker     // This covers the binderRpcToTrustyTest case on Android.
94*38e8c45fSAndroid Build Coastguard Worker     return false;
95*38e8c45fSAndroid Build Coastguard Worker #endif
96*38e8c45fSAndroid Build Coastguard Worker #ifdef __ANDROID__
97*38e8c45fSAndroid Build Coastguard Worker     return base::GetProperty("ro.build.version.codename", "") != "REL";
98*38e8c45fSAndroid Build Coastguard Worker #else
99*38e8c45fSAndroid Build Coastguard Worker     return false;
100*38e8c45fSAndroid Build Coastguard Worker #endif
101*38e8c45fSAndroid Build Coastguard Worker }
102*38e8c45fSAndroid Build Coastguard Worker 
testVersions()103*38e8c45fSAndroid Build Coastguard Worker static inline std::vector<uint32_t> testVersions() {
104*38e8c45fSAndroid Build Coastguard Worker     std::vector<uint32_t> versions;
105*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < RPC_WIRE_PROTOCOL_VERSION_NEXT; i++) {
106*38e8c45fSAndroid Build Coastguard Worker         versions.push_back(i);
107*38e8c45fSAndroid Build Coastguard Worker     }
108*38e8c45fSAndroid Build Coastguard Worker     if (hasExperimentalRpc()) {
109*38e8c45fSAndroid Build Coastguard Worker         versions.push_back(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
110*38e8c45fSAndroid Build Coastguard Worker     }
111*38e8c45fSAndroid Build Coastguard Worker     return versions;
112*38e8c45fSAndroid Build Coastguard Worker }
113*38e8c45fSAndroid Build Coastguard Worker 
trustyIpcPort(uint32_t serverVersion)114*38e8c45fSAndroid Build Coastguard Worker static inline std::string trustyIpcPort(uint32_t serverVersion) {
115*38e8c45fSAndroid Build Coastguard Worker     return "com.android.trusty.binderRpcTestService.V" + std::to_string(serverVersion);
116*38e8c45fSAndroid Build Coastguard Worker }
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker enum class SocketType {
119*38e8c45fSAndroid Build Coastguard Worker     PRECONNECTED,
120*38e8c45fSAndroid Build Coastguard Worker     UNIX,
121*38e8c45fSAndroid Build Coastguard Worker     UNIX_BOOTSTRAP,
122*38e8c45fSAndroid Build Coastguard Worker     UNIX_RAW,
123*38e8c45fSAndroid Build Coastguard Worker     VSOCK,
124*38e8c45fSAndroid Build Coastguard Worker     INET,
125*38e8c45fSAndroid Build Coastguard Worker     TIPC,
126*38e8c45fSAndroid Build Coastguard Worker };
127*38e8c45fSAndroid Build Coastguard Worker 
PrintToString(SocketType socketType)128*38e8c45fSAndroid Build Coastguard Worker static inline std::string PrintToString(SocketType socketType) {
129*38e8c45fSAndroid Build Coastguard Worker     switch (socketType) {
130*38e8c45fSAndroid Build Coastguard Worker         case SocketType::PRECONNECTED:
131*38e8c45fSAndroid Build Coastguard Worker             return "preconnected_uds";
132*38e8c45fSAndroid Build Coastguard Worker         case SocketType::UNIX:
133*38e8c45fSAndroid Build Coastguard Worker             return "unix_domain_socket";
134*38e8c45fSAndroid Build Coastguard Worker         case SocketType::UNIX_BOOTSTRAP:
135*38e8c45fSAndroid Build Coastguard Worker             return "unix_domain_socket_bootstrap";
136*38e8c45fSAndroid Build Coastguard Worker         case SocketType::UNIX_RAW:
137*38e8c45fSAndroid Build Coastguard Worker             return "raw_uds";
138*38e8c45fSAndroid Build Coastguard Worker         case SocketType::VSOCK:
139*38e8c45fSAndroid Build Coastguard Worker             return "vm_socket";
140*38e8c45fSAndroid Build Coastguard Worker         case SocketType::INET:
141*38e8c45fSAndroid Build Coastguard Worker             return "inet_socket";
142*38e8c45fSAndroid Build Coastguard Worker         case SocketType::TIPC:
143*38e8c45fSAndroid Build Coastguard Worker             return "trusty_ipc";
144*38e8c45fSAndroid Build Coastguard Worker         default:
145*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Unknown socket type");
146*38e8c45fSAndroid Build Coastguard Worker             return "";
147*38e8c45fSAndroid Build Coastguard Worker     }
148*38e8c45fSAndroid Build Coastguard Worker }
149*38e8c45fSAndroid Build Coastguard Worker 
epochMillis()150*38e8c45fSAndroid Build Coastguard Worker static inline size_t epochMillis() {
151*38e8c45fSAndroid Build Coastguard Worker     using std::chrono::duration_cast;
152*38e8c45fSAndroid Build Coastguard Worker     using std::chrono::milliseconds;
153*38e8c45fSAndroid Build Coastguard Worker     using std::chrono::seconds;
154*38e8c45fSAndroid Build Coastguard Worker     using std::chrono::system_clock;
155*38e8c45fSAndroid Build Coastguard Worker     return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
156*38e8c45fSAndroid Build Coastguard Worker }
157*38e8c45fSAndroid Build Coastguard Worker 
158*38e8c45fSAndroid Build Coastguard Worker struct BinderRpcOptions {
159*38e8c45fSAndroid Build Coastguard Worker     size_t numThreads = 1;
160*38e8c45fSAndroid Build Coastguard Worker     size_t numSessions = 1;
161*38e8c45fSAndroid Build Coastguard Worker     // right now, this can be empty, or length numSessions, where each value
162*38e8c45fSAndroid Build Coastguard Worker     // represents the info for the corresponding session, but we should
163*38e8c45fSAndroid Build Coastguard Worker     // probably switch this to be a list of sessions options so that other
164*38e8c45fSAndroid Build Coastguard Worker     // options can all be specified per session
165*38e8c45fSAndroid Build Coastguard Worker     std::vector<size_t> numIncomingConnectionsBySession = {};
166*38e8c45fSAndroid Build Coastguard Worker     size_t numOutgoingConnections = SIZE_MAX;
167*38e8c45fSAndroid Build Coastguard Worker     RpcSession::FileDescriptorTransportMode clientFileDescriptorTransportMode =
168*38e8c45fSAndroid Build Coastguard Worker             RpcSession::FileDescriptorTransportMode::NONE;
169*38e8c45fSAndroid Build Coastguard Worker     std::vector<RpcSession::FileDescriptorTransportMode>
170*38e8c45fSAndroid Build Coastguard Worker             serverSupportedFileDescriptorTransportModes = {
171*38e8c45fSAndroid Build Coastguard Worker                     RpcSession::FileDescriptorTransportMode::NONE};
172*38e8c45fSAndroid Build Coastguard Worker 
173*38e8c45fSAndroid Build Coastguard Worker     // If true, connection failures will result in `ProcessSession::sessions` being empty
174*38e8c45fSAndroid Build Coastguard Worker     // instead of a fatal error.
175*38e8c45fSAndroid Build Coastguard Worker     bool allowConnectFailure = false;
176*38e8c45fSAndroid Build Coastguard Worker };
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker #ifndef __TRUSTY__
writeString(binder::borrowed_fd fd,std::string_view str)179*38e8c45fSAndroid Build Coastguard Worker static inline void writeString(binder::borrowed_fd fd, std::string_view str) {
180*38e8c45fSAndroid Build Coastguard Worker     uint64_t length = str.length();
181*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, &length, sizeof(length)));
182*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!android::binder::WriteFully(fd, str.data(), str.length()));
183*38e8c45fSAndroid Build Coastguard Worker }
184*38e8c45fSAndroid Build Coastguard Worker 
readString(binder::borrowed_fd fd)185*38e8c45fSAndroid Build Coastguard Worker static inline std::string readString(binder::borrowed_fd fd) {
186*38e8c45fSAndroid Build Coastguard Worker     uint64_t length;
187*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, &length, sizeof(length)));
188*38e8c45fSAndroid Build Coastguard Worker     std::string ret(length, '\0');
189*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!android::binder::ReadFully(fd, ret.data(), length));
190*38e8c45fSAndroid Build Coastguard Worker     return ret;
191*38e8c45fSAndroid Build Coastguard Worker }
192*38e8c45fSAndroid Build Coastguard Worker 
writeToFd(binder::borrowed_fd fd,const Parcelable & parcelable)193*38e8c45fSAndroid Build Coastguard Worker static inline void writeToFd(binder::borrowed_fd fd, const Parcelable& parcelable) {
194*38e8c45fSAndroid Build Coastguard Worker     Parcel parcel;
195*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(OK != parcelable.writeToParcel(&parcel));
196*38e8c45fSAndroid Build Coastguard Worker     writeString(fd, std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker 
199*38e8c45fSAndroid Build Coastguard Worker template <typename T>
readFromFd(binder::borrowed_fd fd)200*38e8c45fSAndroid Build Coastguard Worker static inline T readFromFd(binder::borrowed_fd fd) {
201*38e8c45fSAndroid Build Coastguard Worker     std::string data = readString(fd);
202*38e8c45fSAndroid Build Coastguard Worker     Parcel parcel;
203*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(OK !=
204*38e8c45fSAndroid Build Coastguard Worker                         parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
205*38e8c45fSAndroid Build Coastguard Worker     T object;
206*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(OK != object.readFromParcel(&parcel));
207*38e8c45fSAndroid Build Coastguard Worker     return object;
208*38e8c45fSAndroid Build Coastguard Worker }
209*38e8c45fSAndroid Build Coastguard Worker 
210*38e8c45fSAndroid Build Coastguard Worker static inline std::unique_ptr<RpcTransportCtxFactory> newTlsFactory(
211*38e8c45fSAndroid Build Coastguard Worker         RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
212*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<RpcAuth> auth = nullptr) {
213*38e8c45fSAndroid Build Coastguard Worker     switch (rpcSecurity) {
214*38e8c45fSAndroid Build Coastguard Worker         case RpcSecurity::RAW:
215*38e8c45fSAndroid Build Coastguard Worker             return RpcTransportCtxFactoryRaw::make();
216*38e8c45fSAndroid Build Coastguard Worker         case RpcSecurity::TLS: {
217*38e8c45fSAndroid Build Coastguard Worker             if (verifier == nullptr) {
218*38e8c45fSAndroid Build Coastguard Worker                 verifier = std::make_shared<RpcCertificateVerifierSimple>();
219*38e8c45fSAndroid Build Coastguard Worker             }
220*38e8c45fSAndroid Build Coastguard Worker             if (auth == nullptr) {
221*38e8c45fSAndroid Build Coastguard Worker                 auth = std::make_unique<RpcAuthSelfSigned>();
222*38e8c45fSAndroid Build Coastguard Worker             }
223*38e8c45fSAndroid Build Coastguard Worker             return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
224*38e8c45fSAndroid Build Coastguard Worker         }
225*38e8c45fSAndroid Build Coastguard Worker         default:
226*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", static_cast<int>(rpcSecurity));
227*38e8c45fSAndroid Build Coastguard Worker     }
228*38e8c45fSAndroid Build Coastguard Worker }
229*38e8c45fSAndroid Build Coastguard Worker 
230*38e8c45fSAndroid Build Coastguard Worker // Create an FD that returns `contents` when read.
mockFileDescriptor(std::string contents)231*38e8c45fSAndroid Build Coastguard Worker static inline binder::unique_fd mockFileDescriptor(std::string contents) {
232*38e8c45fSAndroid Build Coastguard Worker     binder::unique_fd readFd, writeFd;
233*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!binder::Pipe(&readFd, &writeFd), "%s", strerror(errno));
234*38e8c45fSAndroid Build Coastguard Worker     RpcMaybeThread([writeFd = std::move(writeFd), contents = std::move(contents)]() {
235*38e8c45fSAndroid Build Coastguard Worker         signal(SIGPIPE, SIG_IGN); // ignore possible SIGPIPE from the write
236*38e8c45fSAndroid Build Coastguard Worker         if (!android::binder::WriteStringToFd(contents, writeFd)) {
237*38e8c45fSAndroid Build Coastguard Worker             int savedErrno = errno;
238*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(EPIPE != savedErrno, "mockFileDescriptor write failed: %s",
239*38e8c45fSAndroid Build Coastguard Worker                                 strerror(savedErrno));
240*38e8c45fSAndroid Build Coastguard Worker         }
241*38e8c45fSAndroid Build Coastguard Worker     }).detach();
242*38e8c45fSAndroid Build Coastguard Worker     return readFd;
243*38e8c45fSAndroid Build Coastguard Worker }
244*38e8c45fSAndroid Build Coastguard Worker #endif // __TRUSTY__
245*38e8c45fSAndroid Build Coastguard Worker 
246*38e8c45fSAndroid Build Coastguard Worker // A threadsafe channel where writes block until the value is read.
247*38e8c45fSAndroid Build Coastguard Worker template <typename T>
248*38e8c45fSAndroid Build Coastguard Worker class HandoffChannel {
249*38e8c45fSAndroid Build Coastguard Worker public:
write(T v)250*38e8c45fSAndroid Build Coastguard Worker     void write(T v) {
251*38e8c45fSAndroid Build Coastguard Worker         {
252*38e8c45fSAndroid Build Coastguard Worker             RpcMutexUniqueLock lock(mMutex);
253*38e8c45fSAndroid Build Coastguard Worker             // Wait for space to send.
254*38e8c45fSAndroid Build Coastguard Worker             mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
255*38e8c45fSAndroid Build Coastguard Worker             mValue.emplace(std::move(v));
256*38e8c45fSAndroid Build Coastguard Worker         }
257*38e8c45fSAndroid Build Coastguard Worker         mCvFull.notify_all();
258*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock lock(mMutex);
259*38e8c45fSAndroid Build Coastguard Worker         // Wait for it to be taken.
260*38e8c45fSAndroid Build Coastguard Worker         mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
261*38e8c45fSAndroid Build Coastguard Worker     }
262*38e8c45fSAndroid Build Coastguard Worker 
read()263*38e8c45fSAndroid Build Coastguard Worker     T read() {
264*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock lock(mMutex);
265*38e8c45fSAndroid Build Coastguard Worker         if (!mValue.has_value()) {
266*38e8c45fSAndroid Build Coastguard Worker             mCvFull.wait(lock, [&]() { return mValue.has_value(); });
267*38e8c45fSAndroid Build Coastguard Worker         }
268*38e8c45fSAndroid Build Coastguard Worker         T v = std::move(mValue.value());
269*38e8c45fSAndroid Build Coastguard Worker         mValue.reset();
270*38e8c45fSAndroid Build Coastguard Worker         lock.unlock();
271*38e8c45fSAndroid Build Coastguard Worker         mCvEmpty.notify_all();
272*38e8c45fSAndroid Build Coastguard Worker         return v;
273*38e8c45fSAndroid Build Coastguard Worker     }
274*38e8c45fSAndroid Build Coastguard Worker 
275*38e8c45fSAndroid Build Coastguard Worker private:
276*38e8c45fSAndroid Build Coastguard Worker     RpcMutex mMutex;
277*38e8c45fSAndroid Build Coastguard Worker     RpcConditionVariable mCvEmpty;
278*38e8c45fSAndroid Build Coastguard Worker     RpcConditionVariable mCvFull;
279*38e8c45fSAndroid Build Coastguard Worker     std::optional<T> mValue;
280*38e8c45fSAndroid Build Coastguard Worker };
281*38e8c45fSAndroid Build Coastguard Worker 
282*38e8c45fSAndroid Build Coastguard Worker using android::binder::Status;
283*38e8c45fSAndroid Build Coastguard Worker 
284*38e8c45fSAndroid Build Coastguard Worker class MyBinderRpcSession : public BnBinderRpcSession {
285*38e8c45fSAndroid Build Coastguard Worker public:
286*38e8c45fSAndroid Build Coastguard Worker     static std::atomic<int32_t> gNum;
287*38e8c45fSAndroid Build Coastguard Worker 
MyBinderRpcSession(const std::string & name)288*38e8c45fSAndroid Build Coastguard Worker     MyBinderRpcSession(const std::string& name) : mName(name) { gNum++; }
getName(std::string * name)289*38e8c45fSAndroid Build Coastguard Worker     Status getName(std::string* name) override {
290*38e8c45fSAndroid Build Coastguard Worker         *name = mName;
291*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
292*38e8c45fSAndroid Build Coastguard Worker     }
~MyBinderRpcSession()293*38e8c45fSAndroid Build Coastguard Worker     ~MyBinderRpcSession() { gNum--; }
294*38e8c45fSAndroid Build Coastguard Worker 
295*38e8c45fSAndroid Build Coastguard Worker private:
296*38e8c45fSAndroid Build Coastguard Worker     std::string mName;
297*38e8c45fSAndroid Build Coastguard Worker };
298*38e8c45fSAndroid Build Coastguard Worker 
299*38e8c45fSAndroid Build Coastguard Worker class MyBinderRpcCallback : public BnBinderRpcCallback {
sendCallback(const std::string & value)300*38e8c45fSAndroid Build Coastguard Worker     Status sendCallback(const std::string& value) {
301*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock _l(mMutex);
302*38e8c45fSAndroid Build Coastguard Worker         mValues.push_back(value);
303*38e8c45fSAndroid Build Coastguard Worker         _l.unlock();
304*38e8c45fSAndroid Build Coastguard Worker         mCv.notify_one();
305*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
306*38e8c45fSAndroid Build Coastguard Worker     }
sendOnewayCallback(const std::string & value)307*38e8c45fSAndroid Build Coastguard Worker     Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
308*38e8c45fSAndroid Build Coastguard Worker 
309*38e8c45fSAndroid Build Coastguard Worker public:
310*38e8c45fSAndroid Build Coastguard Worker     RpcMutex mMutex;
311*38e8c45fSAndroid Build Coastguard Worker     RpcConditionVariable mCv;
312*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::string> mValues;
313*38e8c45fSAndroid Build Coastguard Worker };
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker // Base class for all concrete implementations of MyBinderRpcTest.
316*38e8c45fSAndroid Build Coastguard Worker // Sub-classes that want to provide a full implementation should derive
317*38e8c45fSAndroid Build Coastguard Worker // from this class instead of MyBinderRpcTestDefault below so the compiler
318*38e8c45fSAndroid Build Coastguard Worker // checks that all methods are implemented.
319*38e8c45fSAndroid Build Coastguard Worker class MyBinderRpcTestBase : public BnBinderRpcTest {
320*38e8c45fSAndroid Build Coastguard Worker public:
321*38e8c45fSAndroid Build Coastguard Worker     int port = 0;
322*38e8c45fSAndroid Build Coastguard Worker 
sendString(const std::string & str)323*38e8c45fSAndroid Build Coastguard Worker     Status sendString(const std::string& str) override {
324*38e8c45fSAndroid Build Coastguard Worker         (void)str;
325*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
326*38e8c45fSAndroid Build Coastguard Worker     }
doubleString(const std::string & str,std::string * strstr)327*38e8c45fSAndroid Build Coastguard Worker     Status doubleString(const std::string& str, std::string* strstr) override {
328*38e8c45fSAndroid Build Coastguard Worker         *strstr = str + str;
329*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
330*38e8c45fSAndroid Build Coastguard Worker     }
getClientPort(int * out)331*38e8c45fSAndroid Build Coastguard Worker     Status getClientPort(int* out) override {
332*38e8c45fSAndroid Build Coastguard Worker         *out = port;
333*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
334*38e8c45fSAndroid Build Coastguard Worker     }
getNullBinder(sp<IBinder> * out)335*38e8c45fSAndroid Build Coastguard Worker     Status getNullBinder(sp<IBinder>* out) override {
336*38e8c45fSAndroid Build Coastguard Worker         out->clear();
337*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
338*38e8c45fSAndroid Build Coastguard Worker     }
pingMe(const sp<IBinder> & binder,int32_t * out)339*38e8c45fSAndroid Build Coastguard Worker     Status pingMe(const sp<IBinder>& binder, int32_t* out) override {
340*38e8c45fSAndroid Build Coastguard Worker         if (binder == nullptr) {
341*38e8c45fSAndroid Build Coastguard Worker             std::cout << "Received null binder!" << std::endl;
342*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_NULL_POINTER);
343*38e8c45fSAndroid Build Coastguard Worker         }
344*38e8c45fSAndroid Build Coastguard Worker         *out = binder->pingBinder();
345*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
346*38e8c45fSAndroid Build Coastguard Worker     }
repeatBinder(const sp<IBinder> & binder,sp<IBinder> * out)347*38e8c45fSAndroid Build Coastguard Worker     Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
348*38e8c45fSAndroid Build Coastguard Worker         *out = binder;
349*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
350*38e8c45fSAndroid Build Coastguard Worker     }
351*38e8c45fSAndroid Build Coastguard Worker     static sp<IBinder> mHeldBinder;
holdBinder(const sp<IBinder> & binder)352*38e8c45fSAndroid Build Coastguard Worker     Status holdBinder(const sp<IBinder>& binder) override {
353*38e8c45fSAndroid Build Coastguard Worker         mHeldBinder = binder;
354*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
355*38e8c45fSAndroid Build Coastguard Worker     }
getHeldBinder(sp<IBinder> * held)356*38e8c45fSAndroid Build Coastguard Worker     Status getHeldBinder(sp<IBinder>* held) override {
357*38e8c45fSAndroid Build Coastguard Worker         *held = mHeldBinder;
358*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
359*38e8c45fSAndroid Build Coastguard Worker     }
nestMe(const sp<IBinderRpcTest> & binder,int count)360*38e8c45fSAndroid Build Coastguard Worker     Status nestMe(const sp<IBinderRpcTest>& binder, int count) override {
361*38e8c45fSAndroid Build Coastguard Worker         if (count <= 0) return Status::ok();
362*38e8c45fSAndroid Build Coastguard Worker         return binder->nestMe(this, count - 1);
363*38e8c45fSAndroid Build Coastguard Worker     }
alwaysGiveMeTheSameBinder(sp<IBinder> * out)364*38e8c45fSAndroid Build Coastguard Worker     Status alwaysGiveMeTheSameBinder(sp<IBinder>* out) override {
365*38e8c45fSAndroid Build Coastguard Worker         static sp<IBinder> binder = new BBinder;
366*38e8c45fSAndroid Build Coastguard Worker         *out = binder;
367*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
368*38e8c45fSAndroid Build Coastguard Worker     }
openSession(const std::string & name,sp<IBinderRpcSession> * out)369*38e8c45fSAndroid Build Coastguard Worker     Status openSession(const std::string& name, sp<IBinderRpcSession>* out) override {
370*38e8c45fSAndroid Build Coastguard Worker         *out = new MyBinderRpcSession(name);
371*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
372*38e8c45fSAndroid Build Coastguard Worker     }
getNumOpenSessions(int32_t * out)373*38e8c45fSAndroid Build Coastguard Worker     Status getNumOpenSessions(int32_t* out) override {
374*38e8c45fSAndroid Build Coastguard Worker         *out = MyBinderRpcSession::gNum;
375*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
376*38e8c45fSAndroid Build Coastguard Worker     }
377*38e8c45fSAndroid Build Coastguard Worker 
378*38e8c45fSAndroid Build Coastguard Worker     RpcMutex blockMutex;
lock()379*38e8c45fSAndroid Build Coastguard Worker     Status lock() override {
380*38e8c45fSAndroid Build Coastguard Worker         blockMutex.lock();
381*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
382*38e8c45fSAndroid Build Coastguard Worker     }
unlockInMsAsync(int32_t ms)383*38e8c45fSAndroid Build Coastguard Worker     Status unlockInMsAsync(int32_t ms) override {
384*38e8c45fSAndroid Build Coastguard Worker         usleep(ms * 1000);
385*38e8c45fSAndroid Build Coastguard Worker         blockMutex.unlock();
386*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
387*38e8c45fSAndroid Build Coastguard Worker     }
lockUnlock()388*38e8c45fSAndroid Build Coastguard Worker     Status lockUnlock() override {
389*38e8c45fSAndroid Build Coastguard Worker         RpcMutexLockGuard _l(blockMutex);
390*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
391*38e8c45fSAndroid Build Coastguard Worker     }
392*38e8c45fSAndroid Build Coastguard Worker 
sleepMs(int32_t ms)393*38e8c45fSAndroid Build Coastguard Worker     Status sleepMs(int32_t ms) override {
394*38e8c45fSAndroid Build Coastguard Worker         usleep(ms * 1000);
395*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
396*38e8c45fSAndroid Build Coastguard Worker     }
397*38e8c45fSAndroid Build Coastguard Worker 
sleepMsAsync(int32_t ms)398*38e8c45fSAndroid Build Coastguard Worker     Status sleepMsAsync(int32_t ms) override {
399*38e8c45fSAndroid Build Coastguard Worker         // In-process binder calls are asynchronous, but the call to this method
400*38e8c45fSAndroid Build Coastguard Worker         // is synchronous wrt its client. This in/out-process threading model
401*38e8c45fSAndroid Build Coastguard Worker         // diffentiation is a classic binder leaky abstraction (for better or
402*38e8c45fSAndroid Build Coastguard Worker         // worse) and is preserved here the way binder sockets plugs itself
403*38e8c45fSAndroid Build Coastguard Worker         // into BpBinder, as nothing is changed at the higher levels
404*38e8c45fSAndroid Build Coastguard Worker         // (IInterface) which result in this behavior.
405*38e8c45fSAndroid Build Coastguard Worker         return sleepMs(ms);
406*38e8c45fSAndroid Build Coastguard Worker     }
407*38e8c45fSAndroid Build Coastguard Worker 
doCallback(const sp<IBinderRpcCallback> & callback,bool oneway,bool delayed,const std::string & value)408*38e8c45fSAndroid Build Coastguard Worker     Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
409*38e8c45fSAndroid Build Coastguard Worker                       const std::string& value) override {
410*38e8c45fSAndroid Build Coastguard Worker         if (callback == nullptr) {
411*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_NULL_POINTER);
412*38e8c45fSAndroid Build Coastguard Worker         }
413*38e8c45fSAndroid Build Coastguard Worker 
414*38e8c45fSAndroid Build Coastguard Worker         if (delayed) {
415*38e8c45fSAndroid Build Coastguard Worker             RpcMaybeThread([=, this]() {
416*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Executing delayed callback: '%s'", value.c_str());
417*38e8c45fSAndroid Build Coastguard Worker                 Status status = doCallback(callback, oneway, false, value);
418*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
419*38e8c45fSAndroid Build Coastguard Worker             }).detach();
420*38e8c45fSAndroid Build Coastguard Worker             return Status::ok();
421*38e8c45fSAndroid Build Coastguard Worker         }
422*38e8c45fSAndroid Build Coastguard Worker 
423*38e8c45fSAndroid Build Coastguard Worker         if (oneway) {
424*38e8c45fSAndroid Build Coastguard Worker             return callback->sendOnewayCallback(value);
425*38e8c45fSAndroid Build Coastguard Worker         }
426*38e8c45fSAndroid Build Coastguard Worker 
427*38e8c45fSAndroid Build Coastguard Worker         return callback->sendCallback(value);
428*38e8c45fSAndroid Build Coastguard Worker     }
429*38e8c45fSAndroid Build Coastguard Worker 
doCallbackAsync(const sp<IBinderRpcCallback> & callback,bool oneway,bool delayed,const std::string & value)430*38e8c45fSAndroid Build Coastguard Worker     Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
431*38e8c45fSAndroid Build Coastguard Worker                            const std::string& value) override {
432*38e8c45fSAndroid Build Coastguard Worker         return doCallback(callback, oneway, delayed, value);
433*38e8c45fSAndroid Build Coastguard Worker     }
434*38e8c45fSAndroid Build Coastguard Worker 
435*38e8c45fSAndroid Build Coastguard Worker protected:
436*38e8c45fSAndroid Build Coastguard Worker     // Generic version of countBinders that works with both
437*38e8c45fSAndroid Build Coastguard Worker     // RpcServer and RpcServerTrusty
438*38e8c45fSAndroid Build Coastguard Worker     template <typename T>
countBindersImpl(const wp<T> & server,std::vector<int32_t> * out)439*38e8c45fSAndroid Build Coastguard Worker     Status countBindersImpl(const wp<T>& server, std::vector<int32_t>* out) {
440*38e8c45fSAndroid Build Coastguard Worker         sp<T> spServer = server.promote();
441*38e8c45fSAndroid Build Coastguard Worker         if (spServer == nullptr) {
442*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_NULL_POINTER);
443*38e8c45fSAndroid Build Coastguard Worker         }
444*38e8c45fSAndroid Build Coastguard Worker         out->clear();
445*38e8c45fSAndroid Build Coastguard Worker         for (auto session : spServer->listSessions()) {
446*38e8c45fSAndroid Build Coastguard Worker             size_t count = session->state()->countBinders();
447*38e8c45fSAndroid Build Coastguard Worker             out->push_back(count);
448*38e8c45fSAndroid Build Coastguard Worker         }
449*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
450*38e8c45fSAndroid Build Coastguard Worker     }
451*38e8c45fSAndroid Build Coastguard Worker };
452*38e8c45fSAndroid Build Coastguard Worker 
453*38e8c45fSAndroid Build Coastguard Worker // Default implementation of MyBinderRpcTest that can be used as-is
454*38e8c45fSAndroid Build Coastguard Worker // or derived from by classes that only want to implement a subset of
455*38e8c45fSAndroid Build Coastguard Worker // the unimplemented methods
456*38e8c45fSAndroid Build Coastguard Worker class MyBinderRpcTestDefault : public MyBinderRpcTestBase {
457*38e8c45fSAndroid Build Coastguard Worker public:
countBinders(std::vector<int32_t> *)458*38e8c45fSAndroid Build Coastguard Worker     Status countBinders(std::vector<int32_t>* /*out*/) override {
459*38e8c45fSAndroid Build Coastguard Worker         return Status::fromStatusT(UNKNOWN_TRANSACTION);
460*38e8c45fSAndroid Build Coastguard Worker     }
461*38e8c45fSAndroid Build Coastguard Worker 
die(bool)462*38e8c45fSAndroid Build Coastguard Worker     Status die(bool /*cleanup*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
463*38e8c45fSAndroid Build Coastguard Worker 
scheduleShutdown()464*38e8c45fSAndroid Build Coastguard Worker     Status scheduleShutdown() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
465*38e8c45fSAndroid Build Coastguard Worker 
useKernelBinderCallingId()466*38e8c45fSAndroid Build Coastguard Worker     Status useKernelBinderCallingId() override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
467*38e8c45fSAndroid Build Coastguard Worker 
echoAsFile(const std::string &,android::os::ParcelFileDescriptor *)468*38e8c45fSAndroid Build Coastguard Worker     Status echoAsFile(const std::string& /*content*/,
469*38e8c45fSAndroid Build Coastguard Worker                       android::os::ParcelFileDescriptor* /*out*/) override {
470*38e8c45fSAndroid Build Coastguard Worker         return Status::fromStatusT(UNKNOWN_TRANSACTION);
471*38e8c45fSAndroid Build Coastguard Worker     }
472*38e8c45fSAndroid Build Coastguard Worker 
concatFiles(const std::vector<android::os::ParcelFileDescriptor> &,android::os::ParcelFileDescriptor *)473*38e8c45fSAndroid Build Coastguard Worker     Status concatFiles(const std::vector<android::os::ParcelFileDescriptor>& /*files*/,
474*38e8c45fSAndroid Build Coastguard Worker                        android::os::ParcelFileDescriptor* /*out*/) override {
475*38e8c45fSAndroid Build Coastguard Worker         return Status::fromStatusT(UNKNOWN_TRANSACTION);
476*38e8c45fSAndroid Build Coastguard Worker     }
477*38e8c45fSAndroid Build Coastguard Worker 
blockingSendFdOneway(const android::os::ParcelFileDescriptor &)478*38e8c45fSAndroid Build Coastguard Worker     Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& /*fd*/) override {
479*38e8c45fSAndroid Build Coastguard Worker         return Status::fromStatusT(UNKNOWN_TRANSACTION);
480*38e8c45fSAndroid Build Coastguard Worker     }
481*38e8c45fSAndroid Build Coastguard Worker 
blockingRecvFd(android::os::ParcelFileDescriptor *)482*38e8c45fSAndroid Build Coastguard Worker     Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
483*38e8c45fSAndroid Build Coastguard Worker         return Status::fromStatusT(UNKNOWN_TRANSACTION);
484*38e8c45fSAndroid Build Coastguard Worker     }
485*38e8c45fSAndroid Build Coastguard Worker 
blockingSendIntOneway(int)486*38e8c45fSAndroid Build Coastguard Worker     Status blockingSendIntOneway(int /*n*/) override {
487*38e8c45fSAndroid Build Coastguard Worker         return Status::fromStatusT(UNKNOWN_TRANSACTION);
488*38e8c45fSAndroid Build Coastguard Worker     }
489*38e8c45fSAndroid Build Coastguard Worker 
blockingRecvInt(int *)490*38e8c45fSAndroid Build Coastguard Worker     Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
491*38e8c45fSAndroid Build Coastguard Worker };
492*38e8c45fSAndroid Build Coastguard Worker 
493*38e8c45fSAndroid Build Coastguard Worker } // namespace android
494