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