1 // Copyright 2021 gRPC authors.
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 "test/core/transport/binder/end2end/testing_channel_create.h"
16
17 #include <utility>
18
19 #include <grpcpp/security/binder_security_policy.h>
20
21 #include "src/core/ext/transport/binder/transport/binder_transport.h"
22 #include "src/core/ext/transport/binder/wire_format/wire_reader_impl.h"
23 #include "src/core/lib/channel/channel_args.h"
24 #include "src/core/lib/config/core_configuration.h"
25 #include "src/core/lib/surface/channel.h"
26 #include "src/core/lib/surface/channel_create.h"
27 #include "src/core/lib/transport/error_utils.h"
28
29 namespace grpc_binder {
30 namespace end2end_testing {
31
32 namespace {
33 // Since we assume the first half of the transport setup is completed before the
34 // server side enters WireReader::SetupTransport, we need this helper to wait
35 // and finish that part of the negotiation for us.
36 class ServerSetupTransportHelper {
37 public:
ServerSetupTransportHelper()38 ServerSetupTransportHelper()
39 : wire_reader_(std::make_unique<WireReaderImpl>(
40 /*transport_stream_receiver=*/nullptr, /*is_client=*/false,
41 std::make_shared<
42 grpc::experimental::binder::UntrustedSecurityPolicy>())) {
43 std::tie(endpoint_binder_, tx_receiver_) = NewBinderPair(
44 [this](transaction_code_t tx_code, ReadableParcel* parcel, int uid) {
45 return this->wire_reader_->ProcessTransaction(tx_code, parcel, uid);
46 });
47 }
WaitForClientBinder()48 std::unique_ptr<Binder> WaitForClientBinder() {
49 return wire_reader_->RecvSetupTransport();
50 }
51
GetEndpointBinderForClient()52 std::unique_ptr<Binder> GetEndpointBinderForClient() {
53 return std::move(endpoint_binder_);
54 }
55
56 private:
57 std::unique_ptr<WireReaderImpl> wire_reader_;
58 // The endpoint binder for client.
59 std::unique_ptr<Binder> endpoint_binder_;
60 std::unique_ptr<TransactionReceiver> tx_receiver_;
61 };
62 } // namespace
63
64 std::pair<grpc_core::Transport*, grpc_core::Transport*>
CreateClientServerBindersPairForTesting()65 CreateClientServerBindersPairForTesting() {
66 ServerSetupTransportHelper helper;
67 std::unique_ptr<Binder> endpoint_binder = helper.GetEndpointBinderForClient();
68 grpc_core::Transport* client_transport = nullptr;
69
70 struct ThreadArgs {
71 std::unique_ptr<Binder> endpoint_binder;
72 grpc_core::Transport** client_transport;
73 } args;
74
75 args.endpoint_binder = std::move(endpoint_binder);
76 args.client_transport = &client_transport;
77
78 grpc_core::Thread client_thread(
79 "client-thread",
80 [](void* arg) {
81 ThreadArgs* args = static_cast<ThreadArgs*>(arg);
82 std::unique_ptr<Binder> endpoint_binder =
83 std::move(args->endpoint_binder);
84 *args->client_transport = grpc_create_binder_transport_client(
85 std::move(endpoint_binder),
86 std::make_shared<
87 grpc::experimental::binder::UntrustedSecurityPolicy>());
88 },
89 &args);
90 client_thread.Start();
91 grpc_core::Transport* server_transport = grpc_create_binder_transport_server(
92 helper.WaitForClientBinder(),
93 std::make_shared<grpc::experimental::binder::UntrustedSecurityPolicy>());
94 client_thread.Join();
95 return std::make_pair(client_transport, server_transport);
96 }
97
BinderChannelForTesting(grpc::Server * server,const grpc::ChannelArguments & args)98 std::shared_ptr<grpc::Channel> BinderChannelForTesting(
99 grpc::Server* server, const grpc::ChannelArguments& args) {
100 grpc_channel_args channel_args = args.c_channel_args();
101 return grpc::CreateChannelInternal(
102 "",
103 grpc_binder_channel_create_for_testing(server->c_server(), &channel_args,
104 nullptr),
105 std::vector<std::unique_ptr<
106 grpc::experimental::ClientInterceptorFactoryInterface>>());
107 }
108
109 } // namespace end2end_testing
110 } // namespace grpc_binder
111
grpc_binder_channel_create_for_testing(grpc_server * server,const grpc_channel_args * args,void *)112 grpc_channel* grpc_binder_channel_create_for_testing(
113 grpc_server* server, const grpc_channel_args* args, void* /*reserved*/) {
114 grpc_core::ExecCtx exec_ctx;
115
116 auto server_args = grpc_core::CoreConfiguration::Get()
117 .channel_args_preconditioning()
118 .PreconditionChannelArgs(args);
119 auto client_args =
120 server_args.Set(GRPC_ARG_DEFAULT_AUTHORITY, "test.authority");
121
122 grpc_core::Transport *client_transport, *server_transport;
123 std::tie(client_transport, server_transport) =
124 grpc_binder::end2end_testing::CreateClientServerBindersPairForTesting();
125 grpc_error_handle error = grpc_core::Server::FromC(server)->SetupTransport(
126 server_transport, nullptr, server_args, nullptr);
127 GPR_ASSERT(error.ok());
128 auto channel = grpc_core::ChannelCreate(
129 "binder", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport);
130 GPR_ASSERT(channel.ok());
131 return channel->release()->c_ptr();
132 }
133