Add a ChannelArguments option for sepcify custom binder intent (#28723)
User can use
`grpc::ChannelArguments::SetString("grpc.binder.custom_android_intent_action_name", "...")`
to set custom binder intent.
This commit is contained in:
parent
361809aabb
commit
08181286e3
|
|
@ -43,12 +43,17 @@ Java_io_grpc_binder_cpp_exampleclient_ButtonPressHandler_native_1entry(
|
|||
jint result = env->GetJavaVM(&jvm);
|
||||
assert(result == 0);
|
||||
}
|
||||
channel = grpc::experimental::CreateBinderChannel(
|
||||
grpc::ChannelArguments ch_args;
|
||||
// This is not required since "grpc.io.action.BIND" is already the default.
|
||||
ch_args.SetString("grpc.binder.custom_android_intent_action_name",
|
||||
"grpc.io.action.BIND");
|
||||
channel = grpc::experimental::CreateCustomBinderChannel(
|
||||
env, application, "io.grpc.binder.cpp.exampleserver",
|
||||
"io.grpc.binder.cpp.exampleserver.ExportedEndpointService",
|
||||
std::make_shared<
|
||||
grpc::experimental::binder::SameSignatureSecurityPolicy>(
|
||||
jvm, application));
|
||||
jvm, application),
|
||||
ch_args);
|
||||
return env->NewStringUTF("Clicked 1 time, channel created");
|
||||
} else {
|
||||
auto stub = helloworld::Greeter::NewStub(channel);
|
||||
|
|
@ -60,6 +65,9 @@ Java_io_grpc_binder_cpp_exampleclient_ButtonPressHandler_native_1entry(
|
|||
if (status.ok()) {
|
||||
return env->NewStringUTF(response.message().c_str());
|
||||
}
|
||||
return env->NewStringUTF("Clicked more than 1 time. Status not ok");
|
||||
return env->NewStringUTF(
|
||||
std::string("Clicked more than 1 time. Status not ok " +
|
||||
std::to_string(status.error_code()))
|
||||
.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,16 @@
|
|||
#include "src/core/lib/transport/transport.h"
|
||||
#include "src/cpp/client/create_channel_internal.h"
|
||||
|
||||
namespace {
|
||||
// grpc.io.action.BIND is the standard action name for binding to binder
|
||||
// transport server.
|
||||
const char* kStandardActionName = "grpc.io.action.BIND";
|
||||
|
||||
// grpc::ChannelArguments key for specifying custom action name.
|
||||
const char* kCustomIntentActionNameArgKey =
|
||||
"grpc.binder.custom_android_intent_action_name";
|
||||
} // namespace
|
||||
|
||||
namespace grpc {
|
||||
namespace experimental {
|
||||
|
||||
|
|
@ -79,9 +89,36 @@ std::shared_ptr<grpc::Channel> CreateCustomBinderChannel(
|
|||
GPR_ASSERT(jni_env_void != nullptr);
|
||||
GPR_ASSERT(security_policy != nullptr);
|
||||
|
||||
// Generate an unique connection ID that identifies this connection (Useful
|
||||
// for mapping connection between Java and C++ code).
|
||||
std::string connection_id = grpc_binder::GetConnectionIdGenerator()->Generate(
|
||||
std::string(package_name), std::string(class_name));
|
||||
|
||||
grpc_channel_args channel_args_with_custom_action;
|
||||
args.SetChannelArgs(&channel_args_with_custom_action);
|
||||
|
||||
// Check if user set an option to use non-standard action name to bind to
|
||||
// server. At this moment this option is not intend for general production use
|
||||
// and is mainly for stress testing purpose.
|
||||
std::string action_name = kStandardActionName;
|
||||
const grpc_arg* action_name_arg = grpc_channel_args_find(
|
||||
&channel_args_with_custom_action, kCustomIntentActionNameArgKey);
|
||||
if (action_name_arg != nullptr) {
|
||||
// The option is set. Now check if it is a string.
|
||||
char* action_name_arg_string = grpc_channel_arg_get_string(action_name_arg);
|
||||
if (action_name_arg_string != nullptr) {
|
||||
action_name = action_name_arg_string;
|
||||
}
|
||||
}
|
||||
grpc_channel_args* channel_args;
|
||||
{
|
||||
// Passing the key down will cause gRPC internal error for unclear reason.
|
||||
// Remove it here.
|
||||
const char* to_remove[] = {kCustomIntentActionNameArgKey};
|
||||
channel_args = grpc_channel_args_copy_and_remove(
|
||||
&channel_args_with_custom_action, to_remove, 1);
|
||||
}
|
||||
|
||||
// After invoking this Java method, Java code will put endpoint binder into
|
||||
// `EndpointBinderPool` after the connection succeeds
|
||||
// TODO(mingcl): Consider if we want to delay the connection establishment
|
||||
|
|
@ -89,13 +126,11 @@ std::shared_ptr<grpc::Channel> CreateCustomBinderChannel(
|
|||
// see any benifits doing that.
|
||||
grpc_binder::TryEstablishConnection(static_cast<JNIEnv*>(jni_env_void),
|
||||
application, package_name, class_name,
|
||||
connection_id);
|
||||
action_name, connection_id);
|
||||
|
||||
// Set server URI to a URI that contains connection id. The URI will be used
|
||||
// by subchannel connector to obtain correct endpoint binder from
|
||||
// `EndpointBinderPool`.
|
||||
grpc_channel_args channel_args;
|
||||
args.SetChannelArgs(&channel_args);
|
||||
grpc_channel_args* new_args;
|
||||
{
|
||||
grpc_arg server_uri_arg = grpc_channel_arg_string_create(
|
||||
|
|
@ -103,7 +138,7 @@ std::shared_ptr<grpc::Channel> CreateCustomBinderChannel(
|
|||
const_cast<char*>(("binder:" + connection_id).c_str()));
|
||||
const char* to_remove[] = {GRPC_ARG_SERVER_URI};
|
||||
new_args = grpc_channel_args_copy_and_add_and_remove(
|
||||
&channel_args, to_remove, 1, &server_uri_arg, 1);
|
||||
channel_args, to_remove, 1, &server_uri_arg, 1);
|
||||
}
|
||||
|
||||
grpc_binder::GetSecurityPolicySetting()->Set(connection_id, security_policy);
|
||||
|
|
@ -114,6 +149,7 @@ std::shared_ptr<grpc::Channel> CreateCustomBinderChannel(
|
|||
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
|
||||
|
||||
grpc_channel_args_destroy(new_args);
|
||||
grpc_channel_args_destroy(channel_args);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,11 +65,12 @@ jclass FindNativeConnectionHelper(
|
|||
|
||||
void TryEstablishConnection(JNIEnv* env, jobject application,
|
||||
absl::string_view pkg, absl::string_view cls,
|
||||
absl::string_view action_name,
|
||||
absl::string_view conn_id) {
|
||||
std::string method = "tryEstablishConnection";
|
||||
std::string type =
|
||||
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/"
|
||||
"lang/String;)V";
|
||||
"lang/String;Ljava/lang/String;)V";
|
||||
|
||||
jclass cl = FindNativeConnectionHelper(env);
|
||||
if (cl == nullptr) {
|
||||
|
|
@ -84,6 +85,7 @@ void TryEstablishConnection(JNIEnv* env, jobject application,
|
|||
env->CallStaticVoidMethod(cl, mid, application,
|
||||
env->NewStringUTF(std::string(pkg).c_str()),
|
||||
env->NewStringUTF(std::string(cls).c_str()),
|
||||
env->NewStringUTF(std::string(action_name).c_str()),
|
||||
env->NewStringUTF(std::string(conn_id).c_str()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ jclass FindNativeConnectionHelper(
|
|||
// Calls Java method NativeConnectionHelper.tryEstablishConnection
|
||||
void TryEstablishConnection(JNIEnv* env, jobject application,
|
||||
absl::string_view pkg, absl::string_view cls,
|
||||
absl::string_view action_name,
|
||||
absl::string_view conn_id);
|
||||
|
||||
// Calls Java method NativeConnectionHelper.isSignatureMatch.
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ public class GrpcBinderConnection implements ServiceConnection {
|
|||
Log.e(logTag, "Service has disconnected. mConnId = " + mConnId);
|
||||
}
|
||||
|
||||
public void tryConnect(String pkg, String cls) {
|
||||
public void tryConnect(String pkg, String cls, String action_name) {
|
||||
synchronized (this) {
|
||||
Intent intent = new Intent("grpc.io.action.BIND");
|
||||
Intent intent = new Intent(action_name);
|
||||
ComponentName compName = new ComponentName(pkg, cls);
|
||||
intent.setComponent(compName);
|
||||
// Will return true if the system is in the process of bringing up a service that your client
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ final class NativeConnectionHelper {
|
|||
// Maps connection id to GrpcBinderConnection instances
|
||||
static Map<String, GrpcBinderConnection> s = new HashMap<>();
|
||||
|
||||
static void tryEstablishConnection(Context context, String pkg, String cls, String connId) {
|
||||
static void tryEstablishConnection(Context context, String pkg, String cls, String action_name, String connId) {
|
||||
// TODO(mingcl): Assert that connId is unique
|
||||
s.put(connId, new GrpcBinderConnection(context, connId));
|
||||
s.get(connId).tryConnect(pkg, cls);
|
||||
s.get(connId).tryConnect(pkg, cls, action_name);
|
||||
}
|
||||
|
||||
// Returns true if the packages signature of the 2 UIDs match.
|
||||
|
|
|
|||
Loading…
Reference in New Issue