Add endpoint binder pool for client channel creation (#27755)

The pool serves as a buffer for interaction between C++ and Java.

The buffer can let us avoid calling into Java code in channel connector
implementation (which has not been merged yet), simplifies interaction
between C++ and Java.

Temporary changes are made to channel_create.cc to keep the example apps
working but they will be rewrite after we start creating client channel
instead of direct channel.
pull/27530/head
Ming-Chuan 3 years ago committed by GitHub
parent 3181f4e530
commit 4d61638857
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      BUILD
  2. 107
      CMakeLists.txt
  3. 120
      build_autogenerated.yaml
  4. 41
      src/core/ext/transport/binder/client/channel_create.cc
  5. 3
      src/core/ext/transport/binder/client/channel_create.h
  6. 108
      src/core/ext/transport/binder/client/endpoint_binder_pool.cc
  7. 65
      src/core/ext/transport/binder/client/endpoint_binder_pool.h
  8. 19
      src/core/ext/transport/binder/client/jni_utils.cc
  9. 5
      src/core/ext/transport/binder/client/jni_utils.h
  10. 2
      src/core/ext/transport/binder/java/io/grpc/binder/cpp/BUILD
  11. 40
      src/core/ext/transport/binder/java/io/grpc/binder/cpp/GrpcBinderConnection.java
  12. 20
      src/core/ext/transport/binder/java/io/grpc/binder/cpp/NativeConnectionHelper.java
  13. 17
      test/core/transport/binder/BUILD
  14. 76
      test/core/transport/binder/endpoint_binder_pool_test.cc
  15. 24
      tools/run_tests/generated/tests.json

@ -498,6 +498,7 @@ grpc_cc_library(
srcs = [
"src/core/ext/transport/binder/client/channel_create.cc",
"src/core/ext/transport/binder/client/channel_create_impl.cc",
"src/core/ext/transport/binder/client/endpoint_binder_pool.cc",
"src/core/ext/transport/binder/client/jni_utils.cc",
"src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc",
"src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc",
@ -514,6 +515,7 @@ grpc_cc_library(
hdrs = [
"src/core/ext/transport/binder/client/channel_create.h",
"src/core/ext/transport/binder/client/channel_create_impl.h",
"src/core/ext/transport/binder/client/endpoint_binder_pool.h",
"src/core/ext/transport/binder/client/jni_utils.h",
"src/core/ext/transport/binder/security_policy/internal_only_security_policy.h",
"src/core/ext/transport/binder/security_policy/security_policy.h",

107
CMakeLists.txt generated

@ -790,6 +790,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx duplicate_header_bad_client_test)
add_dependencies(buildtests_cxx end2end_binder_transport_test)
add_dependencies(buildtests_cxx end2end_test)
add_dependencies(buildtests_cxx endpoint_binder_pool_test)
add_dependencies(buildtests_cxx endpoint_config_test)
add_dependencies(buildtests_cxx error_details_test)
add_dependencies(buildtests_cxx error_test)
@ -8301,6 +8302,7 @@ add_executable(binder_server_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -8353,6 +8355,7 @@ if(gRPC_BUILD_TESTS)
add_executable(binder_transport_test
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -9968,6 +9971,7 @@ add_executable(end2end_binder_transport_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -10069,6 +10073,105 @@ target_link_libraries(end2end_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(endpoint_binder_pool_test
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
src/core/ext/transport/binder/server/binder_server.cc
src/core/ext/transport/binder/server/binder_server_credentials.cc
src/core/ext/transport/binder/transport/binder_transport.cc
src/core/ext/transport/binder/utils/transport_stream_receiver_impl.cc
src/core/ext/transport/binder/wire_format/binder_android.cc
src/core/ext/transport/binder/wire_format/binder_constants.cc
src/core/ext/transport/binder/wire_format/transaction.cc
src/core/ext/transport/binder/wire_format/wire_reader_impl.cc
src/core/ext/transport/binder/wire_format/wire_writer.cc
src/cpp/client/channel_cc.cc
src/cpp/client/client_callback.cc
src/cpp/client/client_context.cc
src/cpp/client/client_interceptor.cc
src/cpp/client/create_channel.cc
src/cpp/client/create_channel_internal.cc
src/cpp/client/create_channel_posix.cc
src/cpp/client/credentials_cc.cc
src/cpp/client/insecure_credentials.cc
src/cpp/client/secure_credentials.cc
src/cpp/codegen/codegen_init.cc
src/cpp/common/alarm.cc
src/cpp/common/auth_property_iterator.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue_cc.cc
src/cpp/common/core_codegen.cc
src/cpp/common/resource_quota_cc.cc
src/cpp/common/rpc_method.cc
src/cpp/common/secure_auth_context.cc
src/cpp/common/secure_channel_arguments.cc
src/cpp/common/secure_create_auth_context.cc
src/cpp/common/tls_certificate_provider.cc
src/cpp/common/tls_credentials_options.cc
src/cpp/common/tls_credentials_options_util.cc
src/cpp/common/validate_service_config.cc
src/cpp/common/version_cc.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/channel_argument_option.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/external_connection_acceptor_impl.cc
src/cpp/server/health/default_health_check_service.cc
src/cpp/server/health/health_check_service.cc
src/cpp/server/health/health_check_service_server_builder_option.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_callback.cc
src/cpp/server/server_cc.cc
src/cpp/server/server_context.cc
src/cpp/server/server_credentials.cc
src/cpp/server/server_posix.cc
src/cpp/thread_manager/thread_manager.cc
src/cpp/util/byte_buffer_cc.cc
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
test/core/transport/binder/endpoint_binder_pool_test.cc
test/core/transport/binder/mock_objects.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(endpoint_binder_pool_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(endpoint_binder_pool_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -10392,6 +10495,7 @@ if(gRPC_BUILD_TESTS)
add_executable(fake_binder_test
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -15932,6 +16036,7 @@ if(gRPC_BUILD_TESTS)
add_executable(transport_stream_receiver_test
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -16246,6 +16351,7 @@ if(gRPC_BUILD_TESTS)
add_executable(wire_reader_test
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -16344,6 +16450,7 @@ if(gRPC_BUILD_TESTS)
add_executable(wire_writer_test
src/core/ext/transport/binder/client/channel_create.cc
src/core/ext/transport/binder/client/channel_create_impl.cc
src/core/ext/transport/binder/client/endpoint_binder_pool.cc
src/core/ext/transport/binder/client/jni_utils.cc
src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc

@ -4612,6 +4612,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -4637,6 +4638,7 @@ targets:
- src/proto/grpc/testing/simple_messages.proto
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -4662,6 +4664,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -4694,6 +4697,7 @@ targets:
src:
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -5432,6 +5436,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -5458,6 +5463,7 @@ targets:
- src/proto/grpc/testing/simple_messages.proto
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -5496,6 +5502,112 @@ targets:
deps:
- grpc++_test
- grpc++_test_util
- name: endpoint_binder_pool_test
gtest: true
build: test
language: c++
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.h
- src/core/ext/transport/binder/server/binder_server.h
- src/core/ext/transport/binder/server/binder_server_credentials.h
- src/core/ext/transport/binder/transport/binder_stream.h
- src/core/ext/transport/binder/transport/binder_transport.h
- src/core/ext/transport/binder/utils/transport_stream_receiver.h
- src/core/ext/transport/binder/utils/transport_stream_receiver_impl.h
- src/core/ext/transport/binder/wire_format/binder.h
- src/core/ext/transport/binder/wire_format/binder_android.h
- src/core/ext/transport/binder/wire_format/binder_constants.h
- src/core/ext/transport/binder/wire_format/transaction.h
- src/core/ext/transport/binder/wire_format/wire_reader.h
- src/core/ext/transport/binder/wire_format/wire_reader_impl.h
- src/core/ext/transport/binder/wire_format/wire_writer.h
- src/cpp/client/create_channel_internal.h
- src/cpp/client/secure_credentials.h
- src/cpp/common/channel_filter.h
- src/cpp/common/secure_auth_context.h
- src/cpp/common/tls_credentials_options_util.h
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/external_connection_acceptor_impl.h
- src/cpp/server/health/default_health_check_service.h
- src/cpp/server/secure_server_credentials.h
- src/cpp/server/thread_pool_interface.h
- src/cpp/thread_manager/thread_manager.h
- test/core/transport/binder/mock_objects.h
src:
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
- src/core/ext/transport/binder/server/binder_server.cc
- src/core/ext/transport/binder/server/binder_server_credentials.cc
- src/core/ext/transport/binder/transport/binder_transport.cc
- src/core/ext/transport/binder/utils/transport_stream_receiver_impl.cc
- src/core/ext/transport/binder/wire_format/binder_android.cc
- src/core/ext/transport/binder/wire_format/binder_constants.cc
- src/core/ext/transport/binder/wire_format/transaction.cc
- src/core/ext/transport/binder/wire_format/wire_reader_impl.cc
- src/core/ext/transport/binder/wire_format/wire_writer.cc
- src/cpp/client/channel_cc.cc
- src/cpp/client/client_callback.cc
- src/cpp/client/client_context.cc
- src/cpp/client/client_interceptor.cc
- src/cpp/client/create_channel.cc
- src/cpp/client/create_channel_internal.cc
- src/cpp/client/create_channel_posix.cc
- src/cpp/client/credentials_cc.cc
- src/cpp/client/insecure_credentials.cc
- src/cpp/client/secure_credentials.cc
- src/cpp/codegen/codegen_init.cc
- src/cpp/common/alarm.cc
- src/cpp/common/auth_property_iterator.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/channel_filter.cc
- src/cpp/common/completion_queue_cc.cc
- src/cpp/common/core_codegen.cc
- src/cpp/common/resource_quota_cc.cc
- src/cpp/common/rpc_method.cc
- src/cpp/common/secure_auth_context.cc
- src/cpp/common/secure_channel_arguments.cc
- src/cpp/common/secure_create_auth_context.cc
- src/cpp/common/tls_certificate_provider.cc
- src/cpp/common/tls_credentials_options.cc
- src/cpp/common/tls_credentials_options_util.cc
- src/cpp/common/validate_service_config.cc
- src/cpp/common/version_cc.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/channel_argument_option.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/dynamic_thread_pool.cc
- src/cpp/server/external_connection_acceptor_impl.cc
- src/cpp/server/health/default_health_check_service.cc
- src/cpp/server/health/health_check_service.cc
- src/cpp/server/health/health_check_service_server_builder_option.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/secure_server_credentials.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_callback.cc
- src/cpp/server/server_cc.cc
- src/cpp/server/server_context.cc
- src/cpp/server/server_credentials.cc
- src/cpp/server/server_posix.cc
- src/cpp/thread_manager/thread_manager.cc
- src/cpp/util/byte_buffer_cc.cc
- src/cpp/util/status.cc
- src/cpp/util/string_ref.cc
- src/cpp/util/time_cc.cc
- test/core/transport/binder/endpoint_binder_pool_test.cc
- test/core/transport/binder/mock_objects.cc
deps:
- grpc_test_util
uses_polling: false
- name: endpoint_config_test
gtest: true
build: test
@ -5627,6 +5739,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -5659,6 +5772,7 @@ targets:
src:
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -7979,6 +8093,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -8010,6 +8125,7 @@ targets:
src:
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -8167,6 +8283,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -8199,6 +8316,7 @@ targets:
src:
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc
@ -8271,6 +8389,7 @@ targets:
headers:
- src/core/ext/transport/binder/client/channel_create.h
- src/core/ext/transport/binder/client/channel_create_impl.h
- src/core/ext/transport/binder/client/endpoint_binder_pool.h
- src/core/ext/transport/binder/client/jni_utils.h
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.h
- src/core/ext/transport/binder/security_policy/security_policy.h
@ -8303,6 +8422,7 @@ targets:
src:
- src/core/ext/transport/binder/client/channel_create.cc
- src/core/ext/transport/binder/client/channel_create_impl.cc
- src/core/ext/transport/binder/client/endpoint_binder_pool.cc
- src/core/ext/transport/binder/client/jni_utils.cc
- src/core/ext/transport/binder/security_policy/internal_only_security_policy.cc
- src/core/ext/transport/binder/security_policy/untrusted_security_policy.cc

@ -44,6 +44,7 @@
#include <grpcpp/impl/grpc_library.h>
#include "src/core/ext/transport/binder/client/channel_create_impl.h"
#include "src/core/ext/transport/binder/client/endpoint_binder_pool.h"
#include "src/core/ext/transport/binder/client/jni_utils.h"
#include "src/core/ext/transport/binder/transport/binder_transport.h"
#include "src/core/ext/transport/binder/wire_format/binder.h"
@ -55,9 +56,11 @@
namespace grpc {
namespace experimental {
// This should be called before calling CreateBinderChannel
// TODO(mingcl): Invoke a callback and pass binder object to caller after a
// successful bind
// TODO(mingcl): To support multiple binder transport connection at the same
// time, we will need to generate unique connection id for each connection.
// For now we use a fixed connection id. This will be fixed in the next PR
std::string kConnectionId = "connection_id_placeholder";
void BindToOnDeviceServerService(void* jni_env_void, jobject application,
absl::string_view package_name,
absl::string_view class_name) {
@ -71,15 +74,14 @@ void BindToOnDeviceServerService(void* jni_env_void, jobject application,
grpc_binder::CallStaticJavaMethod(jni_env,
"io/grpc/binder/cpp/NativeConnectionHelper",
"tryEstablishConnection",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V",
application, std::string(package_name), std::string(class_name));
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
application, std::string(package_name), std::string(class_name), kConnectionId);
// clang-format on
}
// BindToOndeviceServerService need to be called before this, in a different
// task (due to Android API design). (Reference:
// https://stackoverflow.com/a/3055749)
// TODO(mingcl): Support multiple endpoint binder objects
std::shared_ptr<grpc::Channel> CreateBinderChannel(
void* jni_env_void, jobject application, absl::string_view package_name,
absl::string_view class_name,
@ -93,33 +95,28 @@ std::shared_ptr<grpc::Channel> CreateBinderChannel(
// BindToOndeviceServerService need to be called before this, in a different
// task (due to Android API design). (Reference:
// https://stackoverflow.com/a/3055749)
// TODO(mingcl): Support multiple endpoint binder objects
std::shared_ptr<grpc::Channel> CreateCustomBinderChannel(
void* jni_env_void, jobject /*application*/,
absl::string_view /*package_name*/, absl::string_view /*class_name*/,
void*, jobject /*application*/, absl::string_view /*package_name*/,
absl::string_view /*class_name*/,
std::shared_ptr<grpc::experimental::binder::SecurityPolicy> security_policy,
const ChannelArguments& args) {
GPR_ASSERT(jni_env_void != nullptr);
GPR_ASSERT(security_policy != nullptr);
JNIEnv* jni_env = static_cast<JNIEnv*>(jni_env_void);
// clang-format off
jobject object = grpc_binder::CallStaticJavaMethodForObject(
jni_env,
"io/grpc/binder/cpp/NativeConnectionHelper",
"getServiceBinder",
"()Landroid/os/IBinder;");
// clang-format on
std::unique_ptr<grpc_binder::Binder> endpoint_binder;
grpc_binder::GetEndpointBinderPool()->GetEndpointBinder(
kConnectionId, [&](std::unique_ptr<grpc_binder::Binder> e) {
endpoint_binder = std::move(e);
});
// This assumes the above callback will be called immediately before
// `GetEndpointBinder` returns
GPR_ASSERT(endpoint_binder != nullptr);
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return CreateChannelInternal(
"",
::grpc::internal::CreateChannelFromBinderImpl(
absl::make_unique<grpc_binder::BinderAndroid>(
grpc_binder::FromJavaBinder(jni_env, object)),
security_policy, &channel_args),
std::move(endpoint_binder), security_policy, &channel_args),
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}

@ -34,7 +34,8 @@ namespace experimental {
// This need be called before calling CreateBinderChannel, and the thread need
// to be free before invoking CreateBinderChannel.
// TODO(mingcl): Add more explanation on this after we determine the interfaces.
// TODO(mingcl): This method will be removed after we start creating client
// channel instead of direct channel
void BindToOnDeviceServerService(void* jni_env_void, jobject application,
absl::string_view /*package_name*/,
absl::string_view /*class_name*/);

@ -0,0 +1,108 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/ext/transport/binder/client/endpoint_binder_pool.h"
#include "src/core/ext/transport/binder/client/jni_utils.h"
#ifdef GPR_SUPPORT_BINDER_TRANSPORT
#include <jni.h>
#include "src/core/ext/transport/binder/wire_format/binder_android.h"
extern "C" {
// Adds endpoint binder to binder pool when Java notify us that the endpoint
// binder is ready. This is called from GrpcBinderConnection.java
JNIEXPORT void JNICALL
Java_io_grpc_binder_cpp_GrpcBinderConnection_notifyConnected__Ljava_lang_String_2Landroid_os_IBinder_2(
JNIEnv* jni_env, jobject, jstring conn_id_jstring, jobject ibinder) {
jboolean isCopy;
const char* conn_id = jni_env->GetStringUTFChars(conn_id_jstring, &isCopy);
gpr_log(GPR_ERROR, "%s called with conn_id = %s", __func__, conn_id);
GPR_ASSERT(ibinder != nullptr);
ndk::SpAIBinder aibinder = grpc_binder::FromJavaBinder(jni_env, ibinder);
gpr_log(GPR_ERROR, "aibinder = %p", aibinder.get());
auto b = absl::make_unique<grpc_binder::BinderAndroid>(aibinder);
GPR_ASSERT(b != nullptr);
grpc_binder::GetEndpointBinderPool()->AddEndpointBinder(conn_id,
std::move(b));
if (isCopy == JNI_TRUE) {
jni_env->ReleaseStringUTFChars(conn_id_jstring, conn_id);
}
}
}
#endif // GPR_SUPPORT_BINDER_TRANSPORT
namespace grpc_binder {
void EndpointBinderPool ::GetEndpointBinder(
std::string conn_id,
std::function<void(std::unique_ptr<grpc_binder::Binder>)> cb) {
gpr_log(GPR_ERROR, "GetEndpointBinder %s", conn_id.c_str());
std::unique_ptr<grpc_binder::Binder> b;
{
grpc_core::MutexLock l(&m_);
if (binder_map_.count(conn_id)) {
b = std::move(binder_map_[conn_id]);
binder_map_.erase(conn_id);
GPR_ASSERT(b != nullptr);
} else {
if (pending_requests_.count(conn_id) != 0) {
gpr_log(GPR_ERROR, "Duplicate GetEndpointBinder request. conn_id = %s",
conn_id.c_str());
return;
}
pending_requests_[conn_id] = std::move(cb);
return;
}
}
GPR_ASSERT(b != nullptr);
cb(std::move(b));
}
void EndpointBinderPool::AddEndpointBinder(
std::string conn_id, std::unique_ptr<grpc_binder::Binder> b) {
gpr_log(GPR_ERROR, "AddEndpointBinder %s", conn_id.c_str());
GPR_ASSERT(b != nullptr);
// cb will be set in the following block if there is a pending callback
std::function<void(std::unique_ptr<grpc_binder::Binder>)> cb = nullptr;
{
grpc_core::MutexLock l(&m_);
if (binder_map_.count(conn_id) != 0) {
gpr_log(GPR_ERROR, "EndpointBinder already in the pool. conn_id = %s",
conn_id.c_str());
return;
}
if (pending_requests_.count(conn_id)) {
cb = std::move(pending_requests_[conn_id]);
pending_requests_.erase(conn_id);
} else {
binder_map_[conn_id] = std::move(b);
b = nullptr;
}
}
if (cb != nullptr) {
cb(std::move(b));
}
}
EndpointBinderPool* GetEndpointBinderPool() {
static EndpointBinderPool* p = new EndpointBinderPool();
return p;
}
} // namespace grpc_binder

@ -0,0 +1,65 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_ENDPOINT_BINDER_POOL_H
#define GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_ENDPOINT_BINDER_POOL_H
#include <grpc/support/port_platform.h>
#include <functional>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "src/core/ext/transport/binder/wire_format/binder.h"
#include "src/core/lib/gprpp/sync.h"
namespace grpc_binder {
// This class serves as a buffer of endpoint binders between C++ and
// Java. `AddEndpointBinder` will be indirectly invoked by Java code, and
// `GetEndpointBinder` is for C++ code to register callback to get endpoint
// binder when become available. This simplifies JNI related threading issues
// since both side only need to interact with this buffer in non-blocking
// manner and avoids cross-language callbacks.
class EndpointBinderPool {
public:
// Invokes the callback when the binder corresponding to the conn_id become
// available. If the binder is already available, invokes the callback
// immediately.
// Ownership of the endpoint binder will be transferred to the callback
// function and it will be removed from the pool
void GetEndpointBinder(
std::string conn_id,
std::function<void(std::unique_ptr<grpc_binder::Binder>)> cb);
// Add an endpoint binder to the pool
void AddEndpointBinder(std::string conn_id,
std::unique_ptr<grpc_binder::Binder> b);
private:
grpc_core::Mutex m_;
absl::flat_hash_map<std::string, std::unique_ptr<grpc_binder::Binder>>
binder_map_ ABSL_GUARDED_BY(m_);
absl::flat_hash_map<std::string,
std::function<void(std::unique_ptr<grpc_binder::Binder>)>>
pending_requests_ ABSL_GUARDED_BY(m_);
};
// Returns the singleton
EndpointBinderPool* GetEndpointBinderPool();
} // namespace grpc_binder
#endif // GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_ENDPOINT_BINDER_POOL_H

@ -41,6 +41,25 @@ void CallStaticJavaMethod(JNIEnv* env, const std::string& clazz,
env->NewStringUTF(cls.c_str()));
}
void CallStaticJavaMethod(JNIEnv* env, const std::string& clazz,
const std::string& method, const std::string& type,
jobject application, const std::string& pkg,
const std::string& cls, const std::string& conn_id) {
jclass cl = env->FindClass(clazz.c_str());
if (cl == nullptr) {
gpr_log(GPR_ERROR, "No class %s", clazz.c_str());
}
jmethodID mid = env->GetStaticMethodID(cl, method.c_str(), type.c_str());
if (mid == nullptr) {
gpr_log(GPR_ERROR, "No method id %s", method.c_str());
}
env->CallStaticVoidMethod(
cl, mid, application, env->NewStringUTF(pkg.c_str()),
env->NewStringUTF(cls.c_str()), env->NewStringUTF(conn_id.c_str()));
}
jobject CallStaticJavaMethodForObject(JNIEnv* env, const std::string& clazz,
const std::string& method,
const std::string& type) {

@ -25,13 +25,16 @@
namespace grpc_binder {
// TODO(mingcl): Use string_view
// For now we hard code the arguments of the Java function because this is only
// used to call that single function.
void CallStaticJavaMethod(JNIEnv* env, const std::string& clazz,
const std::string& method, const std::string& type,
jobject application, const std::string& pkg,
const std::string& cls);
void CallStaticJavaMethod(JNIEnv* env, const std::string& clazz,
const std::string& method, const std::string& type,
jobject application, const std::string& pkg,
const std::string& cls, const std::string& conn_id);
jobject CallStaticJavaMethodForObject(JNIEnv* env, const std::string& clazz,
const std::string& method,

@ -19,9 +19,9 @@ licenses(["notice"])
android_library(
name = "connection_helper",
srcs = [
"GrpcBinderConnection.java",
"GrpcCppServerBuilder.java",
"NativeConnectionHelper.java",
"SyncServiceConnection.java",
],
visibility = ["//visibility:public"],
deps = [],

@ -21,29 +21,43 @@ import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
/* Connects to a service synchronously */
public class SyncServiceConnection implements ServiceConnection {
private final String logTag = "SyncServiceConnection";
/* Handles the binder connection state with OnDeviceServer server */
public class GrpcBinderConnection implements ServiceConnection {
private static final String logTag = "GrpcBinderConnection";
private Context mContext;
private IBinder mService;
public SyncServiceConnection(Context context) {
// A string that identifies this service connection
private final String mConnId;
public GrpcBinderConnection(Context context, String connId) {
mContext = context;
mConnId = connId;
}
@Override
public void onNullBinding(ComponentName className) {
// TODO(mingcl): Notify C++ that the connection is never going to happen
Log.e(logTag, "Service returned null IBinder. mConnId = " + mConnId);
}
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
Log.e(logTag, "Service has connected: ");
// TODO(mingcl): Check if service is null here
Log.e(logTag, "Service has connected. mConnId = " + mConnId);
if (service == null) {
// This should not happen since onNullBinding should be invoked instead
throw new IllegalArgumentException("service was null");
}
synchronized (this) {
mService = service;
}
notifyConnected(mConnId, mService);
}
@Override
public void onServiceDisconnected(ComponentName className) {
Log.e(logTag, "Service has disconnected: ");
Log.e(logTag, "Service has disconnected. mConnId = " + mConnId);
}
public void tryConnect(String pkg, String cls) {
@ -56,14 +70,16 @@ public class SyncServiceConnection implements ServiceConnection {
// doesn't have permission to bind to it
boolean result = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
if (result) {
Log.e(logTag, "bindService ok");
Log.e(logTag, "bindService returns ok");
} else {
Log.e(logTag, "bindService not ok");
Log.e(
logTag,
"bindService failed. Maybe the system couldn't find the service or the"
+ " client doesn't have permission to bind to it.");
}
}
}
public IBinder getIBinder() {
return mService;
}
// Calls a function defined in endpoint_binder_pool.cc
private static native void notifyConnected(String connId, IBinder service);
}

@ -15,26 +15,22 @@
package io.grpc.binder.cpp;
import android.content.Context;
import android.os.IBinder;
import android.os.Parcel;
import java.util.HashMap;
import java.util.Map;
/**
* This class will be invoked by gRPC binder transport internal implementation to perform operations
* that are only possible in Java
*/
final class NativeConnectionHelper {
static SyncServiceConnection s;
// Maps connection id to GrpcBinderConnection instances
static Map<String, GrpcBinderConnection> s = new HashMap<>();
static void tryEstablishConnection(Context context, String pkg, String cls) {
s = new SyncServiceConnection(context);
s.tryConnect(pkg, cls);
}
// TODO(mingcl): We should notify C++ once we got the service binder so they don't need to call
// this function to check. For now we assume that this function will only be called after
// successful connection
static IBinder getServiceBinder() {
return s.getIBinder();
static void tryEstablishConnection(Context context, String pkg, String cls, String connId) {
// TODO(mingcl): Assert that connId is unique
s.put(connId, new GrpcBinderConnection(context, connId));
s.get(connId).tryConnect(pkg, cls);
}
static Parcel getEmptyParcel() {

@ -100,3 +100,20 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "endpoint_binder_pool_test",
srcs = ["endpoint_binder_pool_test.cc"],
external_deps = [
"absl/memory",
"gtest",
],
language = "C++",
uses_polling = False,
deps = [
":mock_objects",
"//:grpc",
"//:grpc++_binder",
"//test/core/util:grpc_test_util",
],
)

@ -0,0 +1,76 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/ext/transport/binder/client/endpoint_binder_pool.h"
#include <cassert>
#include <string>
#include <utility>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/memory/memory.h"
#include "src/core/ext/transport/binder/client/endpoint_binder_pool.h"
#include "test/core/transport/binder/mock_objects.h"
#include "test/core/util/test_config.h"
namespace grpc_binder {
class CallbackChecker {
public:
MOCK_METHOD(void, Cb, (std::unique_ptr<grpc_binder::Binder>), ());
};
TEST(EndpointBinderPoolTest, AddBeforeGet) {
EndpointBinderPool pool;
auto b = absl::make_unique<grpc_binder::MockBinder>();
CallbackChecker cc;
pool.AddEndpointBinder("test", std::move(b));
// TODO(mingcl): Use pointer matcher to verify it is `b` being passed back
// here. It is only available in newer gtest version
EXPECT_CALL(cc, Cb(testing::_));
pool.GetEndpointBinder(
"test", std::bind(&CallbackChecker::Cb, &cc, std::placeholders::_1));
}
TEST(EndpointBinderPoolTest, GetBeforeAdd) {
EndpointBinderPool pool;
auto b = absl::make_unique<grpc_binder::MockBinder>();
CallbackChecker cc;
EXPECT_CALL(cc, Cb(testing::_)).Times(0);
pool.GetEndpointBinder(
"test", std::bind(&CallbackChecker::Cb, &cc, std::placeholders::_1));
EXPECT_CALL(cc, Cb(testing::_)).Times(1);
pool.AddEndpointBinder("test", std::move(b));
}
TEST(EndpointBinderPoolTest, ExpectNotCalled) {
EndpointBinderPool pool;
auto b = absl::make_unique<grpc_binder::MockBinder>();
CallbackChecker cc;
EXPECT_CALL(cc, Cb(testing::_)).Times(0);
pool.GetEndpointBinder(
"test", std::bind(&CallbackChecker::Cb, &cc, std::placeholders::_1));
}
} // namespace grpc_binder
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
return RUN_ALL_TESTS();
}

@ -4195,6 +4195,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "endpoint_binder_pool_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save