#include <grpc/support/port_platform.h>
#ifndef GRPC_NO_BINDER
#include "src/core/ext/transport/binder/client/binder_connector.h"
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
#endif
#include <functional>
#include <map>
#include <grpcpp/security/binder_security_policy.h>
#include "src/core/ext/filters/client_channel/connector.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/transport/binder/client/endpoint_binder_pool.h"
#include "src/core/ext/transport/binder/client/security_policy_setting.h"
#include "src/core/ext/transport/binder/transport/binder_transport.h"
#include "src/core/ext/transport/binder/wire_format/binder.h"
namespace {
class BinderConnector : public grpc_core::SubchannelConnector {
public:
BinderConnector() {}
~BinderConnector() override {}
void Connect(const Args& args, Result* result,
grpc_closure* notify) override {
#ifdef GRPC_HAVE_UNIX_SOCKET
{
struct sockaddr_un* un =
reinterpret_cast<struct sockaddr_un*>(args.address->addr);
size_t id_length = args.address->len - sizeof(un->sun_family);
GPR_ASSERT(id_length >= 2);
GPR_ASSERT(un->sun_path[id_length - 1] == '\0');
conn_id_ = un->sun_path;
}
#else
GPR_ASSERT(0);
#endif
gpr_log(GPR_INFO, "BinderConnector %p conn_id_ = %s", this,
conn_id_.c_str());
args_ = args;
GPR_ASSERT(notify_ == nullptr);
GPR_ASSERT(notify != nullptr);
notify_ = notify;
result_ = result;
Ref().release();
grpc_binder::GetEndpointBinderPool()->GetEndpointBinder(
conn_id_,
std::bind(&BinderConnector::OnConnected, this, std::placeholders::_1));
}
void OnConnected(std::unique_ptr<grpc_binder::Binder> endpoint_binder) {
GPR_ASSERT(endpoint_binder != nullptr);
grpc_transport* transport = grpc_create_binder_transport_client(
std::move(endpoint_binder),
grpc_binder::GetSecurityPolicySetting()->Get(conn_id_));
GPR_ASSERT(transport != nullptr);
result_->channel_args = args_.channel_args;
result_->transport = transport;
GPR_ASSERT(notify_ != nullptr);
if (grpc_core::ExecCtx::Get() == nullptr) {
grpc_core::ExecCtx exec_ctx;
grpc_core::ExecCtx::Run(DEBUG_LOCATION, notify_, absl::OkStatus());
} else {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, notify_, absl::OkStatus());
}
Unref();
}
void Shutdown(grpc_error_handle ) override {}
private:
Args args_;
grpc_closure* notify_ = nullptr;
Result* result_ = nullptr;
std::string conn_id_;
};
}
namespace grpc_core {
RefCountedPtr<Subchannel> BinderClientChannelFactory::CreateSubchannel(
const grpc_resolved_address& address, const ChannelArgs& args) {
gpr_log(GPR_INFO, "BinderClientChannelFactory creating subchannel %p", this);
return Subchannel::Create(
MakeOrphanable<BinderConnector>(), address,
args.Set(GRPC_ARG_DEFAULT_AUTHORITY, "binder.authority"));
}
}
#endif