mirror of https://github.com/grpc/grpc.git
Import binder transport channel create interface (#27007)
Also try use the API in example apk to make sure the binder transport code and the rest of gRPC compiles with the Android toolchain We will properly expose our interface later.pull/27069/head
parent
f292f001ee
commit
9da755a61e
12 changed files with 446 additions and 15 deletions
@ -1,30 +1,34 @@ |
||||
// 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 <android/log.h> |
||||
#include <jni.h> |
||||
#include "src/core/ext/transport/binder/client/channel_create.h" |
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL |
||||
Java_io_grpc_binder_cpp_example_ButtonPressHandler_native_1entry( |
||||
JNIEnv* env, jobject /*this*/, jobject /*application*/) { |
||||
JNIEnv* env, jobject /*this*/, jobject application) { |
||||
static bool first = true; |
||||
__android_log_print(ANDROID_LOG_INFO, "Demo", "Line number %d", __LINE__); |
||||
if (first) { |
||||
first = false; |
||||
grpc::experimental::BindToOnDeviceServerService(env, application, "", ""); |
||||
return env->NewStringUTF("Clicked 1 time"); |
||||
} else { |
||||
// Create a channel. For now we only want to make sure it compiles.
|
||||
auto channel = |
||||
grpc::experimental::CreateBinderChannel(env, application, "", ""); |
||||
return env->NewStringUTF("Clicked more than 1 time"); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,71 @@ |
||||
# 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. |
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_cc_library") |
||||
|
||||
licenses(["notice"]) |
||||
|
||||
package( |
||||
default_visibility = ["//visibility:public"], |
||||
) |
||||
|
||||
# TODO(mingcl): See if it is possible to add flags that warns about undefined symbol at link time |
||||
grpc_cc_library( |
||||
name = "grpc_transport_binder_client", |
||||
srcs = [ |
||||
"channel_create.cc", |
||||
"channel_create.h", |
||||
"jni_utils.cc", |
||||
], |
||||
hdrs = [ |
||||
"channel_create.h", |
||||
"jni_utils.h", |
||||
], |
||||
external_deps = [ |
||||
"absl/strings", |
||||
"absl/time", |
||||
], |
||||
deps = [ |
||||
":grpc_transport_binder_client_impl", |
||||
"//:gpr", |
||||
"//:gpr_base", |
||||
"//:grpc", |
||||
"//:grpc++_base", |
||||
"//:grpc_base", |
||||
"//:grpc_base_c", |
||||
"//:grpc_codegen", |
||||
"//src/core/ext/transport/binder/transport", |
||||
"//src/core/ext/transport/binder/utils:transport_stream_receiver", |
||||
"//src/core/ext/transport/binder/wire_format:binder_android", |
||||
"//src/core/ext/transport/binder/wire_format:wire_reader", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_library( |
||||
name = "grpc_transport_binder_client_impl", |
||||
srcs = ["channel_create_impl.cc"], |
||||
hdrs = ["channel_create_impl.h"], |
||||
external_deps = [], |
||||
deps = [ |
||||
"//:gpr", |
||||
"//:gpr_base", |
||||
"//:grpc", |
||||
"//:grpc++_base", |
||||
"//:grpc_base", |
||||
"//:grpc_base_c", |
||||
"//:grpc_codegen", |
||||
"//src/core/ext/transport/binder/transport", |
||||
"//src/core/ext/transport/binder/wire_format:binder", |
||||
], |
||||
) |
@ -0,0 +1,99 @@ |
||||
// 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/impl/codegen/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/client/channel_create.h" |
||||
|
||||
#if defined(ANDROID) || defined(__ANDROID__) |
||||
|
||||
#include <android/binder_auto_utils.h> |
||||
#include <android/binder_ibinder.h> |
||||
#include <android/binder_ibinder_jni.h> |
||||
#include <android/binder_interface_utils.h> |
||||
#include <grpc/grpc.h> |
||||
#include <grpc/grpc_posix.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/port_platform.h> |
||||
#include <grpcpp/impl/grpc_library.h> |
||||
|
||||
#include "absl/memory/memory.h" |
||||
#include "absl/time/clock.h" |
||||
#include "absl/time/time.h" |
||||
#include "src/core/ext/transport/binder/client/channel_create_impl.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" |
||||
#include "src/core/ext/transport/binder/wire_format/binder_android.h" |
||||
#include "src/core/lib/surface/channel.h" |
||||
#include "src/core/lib/transport/transport.h" |
||||
#include "src/cpp/client/create_channel_internal.h" |
||||
|
||||
namespace grpc { |
||||
namespace experimental { |
||||
|
||||
// This should be called before calling CreateBinderChannel
|
||||
// TODO(mingcl): Pass package_name and class_name down to connection helper
|
||||
// TODO(mingcl): Invoke a callback and pass binder object to caller after a
|
||||
// successful bind
|
||||
void BindToOnDeviceServerService(void* jni_env_void, jobject application, |
||||
absl::string_view /*package_name*/, |
||||
absl::string_view /*class_name*/ |
||||
) { |
||||
// Init gRPC library first so gpr_log works
|
||||
grpc::internal::GrpcLibrary init_lib; |
||||
init_lib.init(); |
||||
|
||||
JNIEnv* jni_env = static_cast<JNIEnv*>(jni_env_void); |
||||
|
||||
// clang-format off
|
||||
CallStaticJavaMethod(jni_env, |
||||
"io/grpc/binder/cpp/NativeConnectionHelper", |
||||
"tryEstablishConnection", |
||||
"(Landroid/content/Context;)V", |
||||
application); |
||||
// 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*/) { |
||||
JNIEnv* jni_env = static_cast<JNIEnv*>(jni_env_void); |
||||
|
||||
// clang-format off
|
||||
jobject object = CallStaticJavaMethodForObject( |
||||
jni_env, |
||||
"io/grpc/binder/cpp/NativeConnectionHelper", |
||||
"getServiceBinder", |
||||
"()Landroid/os/IBinder;"); |
||||
// clang-format on
|
||||
|
||||
return CreateChannelInternal( |
||||
"", |
||||
::grpc::internal::CreateChannelFromBinderImpl( |
||||
absl::make_unique<grpc_binder::BinderAndroid>( |
||||
grpc_binder::FromJavaBinder(jni_env, object)), |
||||
nullptr), |
||||
std::vector< |
||||
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>()); |
||||
} |
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
||||
#endif // ANDROID
|
@ -0,0 +1,50 @@ |
||||
// 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_CHANNEL_CREATE_H |
||||
#define GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_H |
||||
|
||||
#if defined(ANDROID) || defined(__ANDROID__) |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#include <grpc/impl/codegen/grpc_types.h> |
||||
#include <grpc/support/port_platform.h> |
||||
#include <grpcpp/channel.h> |
||||
#include <jni.h> |
||||
|
||||
#include "absl/strings/string_view.h" |
||||
|
||||
namespace grpc { |
||||
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.
|
||||
void BindToOnDeviceServerService(void* jni_env_void, jobject application, |
||||
absl::string_view /*package_name*/, |
||||
absl::string_view /*class_name*/); |
||||
|
||||
// Need to be invoked after BindToOnDeviceServerService
|
||||
// Create a new Channel from server package name and service class name
|
||||
std::shared_ptr<grpc::Channel> CreateBinderChannel( |
||||
void* jni_env_void, jobject application, absl::string_view package_name, |
||||
absl::string_view class_name); |
||||
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
||||
#endif |
||||
|
||||
#endif // GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_H
|
@ -0,0 +1,61 @@ |
||||
// 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/impl/codegen/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/client/channel_create_impl.h" |
||||
|
||||
#include <memory> |
||||
#include <utility> |
||||
|
||||
#include "src/core/ext/transport/binder/transport/binder_transport.h" |
||||
#include "src/core/ext/transport/binder/wire_format/binder.h" |
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/surface/api_trace.h" |
||||
#include "src/core/lib/surface/channel.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
grpc_channel* CreateChannelFromBinderImpl( |
||||
std::unique_ptr<grpc_binder::Binder> endpoint_binder, |
||||
const grpc_channel_args* args) { |
||||
grpc_core::ExecCtx exec_ctx; |
||||
GRPC_API_TRACE("grpc_channel_create_from_binder(target=%p, args=%p)", 2, |
||||
((void*)1234, args)); |
||||
|
||||
grpc_transport* transport = |
||||
grpc_create_binder_transport_client(std::move(endpoint_binder)); |
||||
GPR_ASSERT(transport); |
||||
|
||||
// TODO(b/192207753): check binder alive and ping binder
|
||||
|
||||
// TODO(b/192207758): Figure out if we are required to set authority here
|
||||
grpc_arg default_authority_arg = grpc_channel_arg_string_create( |
||||
const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), |
||||
const_cast<char*>("test.authority")); |
||||
grpc_channel_args* final_args = |
||||
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
grpc_channel* channel = grpc_channel_create( |
||||
"binder_target_placeholder", final_args, GRPC_CLIENT_DIRECT_CHANNEL, |
||||
transport, nullptr, 0, &error); |
||||
// TODO(mingcl): Handle error properly
|
||||
GPR_ASSERT(error == GRPC_ERROR_NONE); |
||||
grpc_channel_args_destroy(final_args); |
||||
return channel; |
||||
} |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
@ -0,0 +1,33 @@ |
||||
// 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_CHANNEL_CREATE_IMPL_H |
||||
#define GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_IMPL_H |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/wire_format/binder.h" |
||||
#include "src/core/lib/channel/channel_args.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
grpc_channel* CreateChannelFromBinderImpl( |
||||
std::unique_ptr<grpc_binder::Binder> endpoint_binder, |
||||
const grpc_channel_args* args); |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_IMPL_H
|
@ -0,0 +1,63 @@ |
||||
// 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/impl/codegen/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/client/jni_utils.h" |
||||
|
||||
#include <grpc/support/log.h> |
||||
|
||||
#if defined(ANDROID) || defined(__ANDROID__) |
||||
|
||||
void CallStaticJavaMethod(JNIEnv* env, const std::string& clazz, |
||||
const std::string& method, const std::string& type, |
||||
jobject application) { |
||||
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); |
||||
} |
||||
|
||||
jobject CallStaticJavaMethodForObject(JNIEnv* env, const std::string& clazz, |
||||
const std::string& method, |
||||
const std::string& type) { |
||||
jclass cl = env->FindClass(clazz.c_str()); |
||||
if (cl == nullptr) { |
||||
gpr_log(GPR_ERROR, "No class %s", clazz.c_str()); |
||||
return nullptr; |
||||
} |
||||
|
||||
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()); |
||||
return nullptr; |
||||
} |
||||
|
||||
jobject object = env->CallStaticObjectMethod(cl, mid); |
||||
if (object == nullptr) { |
||||
gpr_log(GPR_ERROR, "Got null object from Java"); |
||||
return nullptr; |
||||
} |
||||
|
||||
return object; |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,38 @@ |
||||
// 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_JNI_UTILS_H |
||||
#define GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_JNI_UTILS_H |
||||
|
||||
#if defined(ANDROID) || defined(__ANDROID__) |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#include <jni.h> |
||||
|
||||
#include <string> |
||||
|
||||
// TODO(mingcl): Put these functions in a proper namespace
|
||||
// TODO(mingcl): Use string_view
|
||||
void CallStaticJavaMethod(JNIEnv* env, const std::string& clazz, |
||||
const std::string& method, const std::string& type, |
||||
jobject application); |
||||
|
||||
jobject CallStaticJavaMethodForObject(JNIEnv* env, const std::string& clazz, |
||||
const std::string& method, |
||||
const std::string& type); |
||||
|
||||
#endif |
||||
|
||||
#endif // GRPC_CORE_EXT_TRANSPORT_BINDER_CLIENT_JNI_UTILS_H
|
Loading…
Reference in new issue