mirror of https://github.com/grpc/grpc.git
commit
d0f149e023
2435 changed files with 12822 additions and 25054 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@ |
||||
# gRPC-core BinderTransport example apps |
||||
|
||||
## Build Instruction |
||||
|
||||
1. Install Android SDK and NDK. Only NDK version >= 25 is supported. We tested against SDK Platform `33` and NDK `26.2.11394342`. |
||||
2. Make sure Bazel is at least `7.0`. Use `export OVERRIDE_BAZEL_VERSION=7.3.1` to selected a supported version listed in `bazel/supported_versions.txt` if necessary. |
||||
3. Point environment variables to install locations of SDK and NDK |
||||
``` |
||||
export ANDROID_HOME=$HOME/android-sdk |
||||
export ANDROID_NDK_HOME=$HOME/android-sdk/ndk/26.2.11394342 |
||||
``` |
||||
4. To build a fat APK that supports `x86_64`, `armv7`, and `arm64`: |
||||
``` |
||||
bazel build \ |
||||
--extra_toolchains=@androidndk//:all \ |
||||
--android_platforms=//bazel/platforms/android:x86_64,//bazel/platforms/android:armeabi-v7a,//bazel/platforms/android:arm64-v8a \ |
||||
--copt=-Wno-unknown-warning-option \ |
||||
//examples/android/binder/java/io/grpc/binder/cpp/exampleserver:app \ |
||||
//examples/android/binder/java/io/grpc/binder/cpp/exampleclient:app |
||||
``` |
||||
5. `adb install |
||||
bazel-bin/examples/android/binder/java/io/grpc/binder/cpp/exampleclient/app.apk` |
||||
6. `adb install |
||||
bazel-bin/examples/android/binder/java/io/grpc/binder/cpp/exampleserver/app.apk` |
@ -1,25 +0,0 @@ |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="io.grpc.binder.cpp.exampleclient" |
||||
android:versionCode="1" |
||||
android:versionName="1.0" > |
||||
|
||||
<uses-sdk |
||||
android:minSdkVersion="29" |
||||
android:targetSdkVersion="30" /> |
||||
|
||||
<queries> |
||||
<package android:name="io.grpc.binder.cpp.exampleserver" /> |
||||
</queries> |
||||
|
||||
<application |
||||
android:label="gRPC BinderTransport Client Cpp"> |
||||
<activity |
||||
android:name=".MainActivity" |
||||
android:label="gRPC BinderTransport Client Cpp" > |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN" /> |
||||
<category android:name="android.intent.category.LAUNCHER" /> |
||||
</intent-filter> |
||||
</activity> |
||||
</application> |
||||
</manifest> |
@ -1,51 +0,0 @@ |
||||
# 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. |
||||
|
||||
cc_library( |
||||
name = "jni_lib", |
||||
srcs = ["native.cc"], |
||||
linkopts = [ |
||||
"-ldl", |
||||
"-llog", |
||||
"-lm", |
||||
"-Wl,--no-undefined", |
||||
], |
||||
deps = [ |
||||
"//:grpc++", |
||||
"//examples/protos:helloworld_cc_grpc", |
||||
], |
||||
alwayslink = True, |
||||
) |
||||
|
||||
android_library( |
||||
name = "activity", |
||||
srcs = [ |
||||
"ButtonPressHandler.java", |
||||
"MainActivity.java", |
||||
], |
||||
manifest = "AndroidManifest.xml", |
||||
resource_files = glob(["res/**"]), |
||||
deps = [ |
||||
":jni_lib", |
||||
"@binder_transport_android_helper//io/grpc/binder/cpp:connection_helper", |
||||
], |
||||
) |
||||
|
||||
android_binary( |
||||
name = "app", |
||||
manifest = "AndroidManifest.xml", |
||||
deps = [ |
||||
":activity", |
||||
], |
||||
) |
@ -1,15 +0,0 @@ |
||||
package io.grpc.binder.cpp.exampleclient; |
||||
|
||||
import android.app.Application; |
||||
|
||||
public class ButtonPressHandler { |
||||
static { |
||||
System.loadLibrary("app"); |
||||
} |
||||
|
||||
public native String native_entry(Application application); |
||||
|
||||
public String onPressed(Application application) { |
||||
return native_entry(application); |
||||
} |
||||
} |
@ -1,26 +0,0 @@ |
||||
package io.grpc.binder.cpp.exampleclient; |
||||
|
||||
import android.app.Activity; |
||||
import android.os.Bundle; |
||||
import android.util.Log; |
||||
import android.widget.Button; |
||||
import android.widget.TextView; |
||||
|
||||
/** Main class for the example app. */ |
||||
public class MainActivity extends Activity { |
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
Log.v("Example", "hello, world"); |
||||
|
||||
setContentView(R.layout.activity_main); |
||||
|
||||
Button clickMeButton = findViewById(R.id.clickMeButton); |
||||
TextView exampleTextView = findViewById(R.id.exampleTextView); |
||||
|
||||
ButtonPressHandler h = new ButtonPressHandler(); |
||||
|
||||
clickMeButton.setOnClickListener( |
||||
v -> exampleTextView.setText(h.onPressed(getApplication()))); |
||||
} |
||||
} |
@ -1,73 +0,0 @@ |
||||
// 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 "examples/protos/helloworld.grpc.pb.h" |
||||
#include "examples/protos/helloworld.pb.h" |
||||
|
||||
#include <grpcpp/create_channel_binder.h> |
||||
#include <grpcpp/security/binder_security_policy.h> |
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL |
||||
Java_io_grpc_binder_cpp_exampleclient_ButtonPressHandler_native_1entry( |
||||
JNIEnv* env, jobject /*this*/, jobject application) { |
||||
// Lower the gRPC logging level, here it is just for demo and debugging
|
||||
// purpose.
|
||||
setenv("GRPC_VERBOSITY", "INFO", true); |
||||
if (grpc::experimental::InitializeBinderChannelJavaClass(env)) { |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoClient", |
||||
"InitializeBinderChannelJavaClass succeed"); |
||||
} else { |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoClient", |
||||
"InitializeBinderChannelJavaClass failed"); |
||||
} |
||||
static bool first = true; |
||||
static std::shared_ptr<grpc::Channel> channel; |
||||
if (first) { |
||||
first = false; |
||||
JavaVM* jvm; |
||||
{ |
||||
jint result = env->GetJavaVM(&jvm); |
||||
assert(result == 0); |
||||
} |
||||
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), |
||||
ch_args); |
||||
return env->NewStringUTF("Clicked 1 time, channel created"); |
||||
} else { |
||||
auto stub = helloworld::Greeter::NewStub(channel); |
||||
grpc::ClientContext context; |
||||
helloworld::HelloRequest request; |
||||
helloworld::HelloReply response; |
||||
request.set_name("BinderTransportClient"); |
||||
grpc::Status status = stub->SayHello(&context, request, &response); |
||||
if (status.ok()) { |
||||
return env->NewStringUTF(response.message().c_str()); |
||||
} |
||||
return env->NewStringUTF( |
||||
std::string("Clicked more than 1 time. Status not ok " + |
||||
std::to_string(status.error_code())) |
||||
.c_str()); |
||||
} |
||||
} |
@ -1,24 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:padding="16dp" |
||||
android:orientation="vertical" |
||||
android:gravity="center_vertical" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<TextView |
||||
android:id="@+id/exampleTextView" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:textSize="32dp" |
||||
android:text="@string/thinking_face"/> |
||||
|
||||
<Button |
||||
android:id="@+id/clickMeButton" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:layout_marginTop="16dp" |
||||
android:text="@string/click_me_button"/> |
||||
</LinearLayout> |
@ -1,5 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<string name="click_me_button">Run example</string> |
||||
<string name="thinking_face">🤔</string> |
||||
</resources> |
@ -1,21 +0,0 @@ |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="io.grpc.binder.cpp.exampleserver" |
||||
android:versionCode="1" |
||||
android:versionName="1.0" > |
||||
|
||||
<uses-sdk |
||||
android:minSdkVersion="29" |
||||
android:targetSdkVersion="30" /> |
||||
|
||||
<application |
||||
android:label="gRPC BinderTransport Server Cpp"> |
||||
<activity |
||||
android:name=".MainActivity" |
||||
android:label="gRPC BinderTransport Server Cpp" > |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN" /> |
||||
<category android:name="android.intent.category.LAUNCHER" /> |
||||
</intent-filter> |
||||
</activity> |
||||
</application> |
||||
</manifest> |
@ -1,10 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="io.grpc.binder.cpp.exampleserver"> |
||||
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="30"/> |
||||
<application> |
||||
<service |
||||
android:name=".ExportedEndpointService" |
||||
android:exported="true"/> |
||||
</application> |
||||
</manifest> |
@ -1,61 +0,0 @@ |
||||
# 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. |
||||
|
||||
cc_library( |
||||
name = "jni_lib", |
||||
srcs = ["native.cc"], |
||||
linkopts = [ |
||||
"-ldl", |
||||
"-llog", |
||||
"-lm", |
||||
"-Wl,--no-undefined", |
||||
], |
||||
deps = [ |
||||
"//:grpc++", |
||||
"//examples/protos:helloworld_cc_grpc", |
||||
], |
||||
alwayslink = True, |
||||
) |
||||
|
||||
android_library( |
||||
name = "activity", |
||||
srcs = [ |
||||
"ButtonPressHandler.java", |
||||
"MainActivity.java", |
||||
], |
||||
manifest = "AndroidManifest.xml", |
||||
resource_files = glob(["res/**"]), |
||||
deps = [ |
||||
":endpoint", |
||||
":jni_lib", |
||||
], |
||||
) |
||||
|
||||
android_library( |
||||
name = "endpoint", |
||||
srcs = ["ExportedEndpointService.java"], |
||||
exports_manifest = True, |
||||
manifest = "AndroidManifest_endpoint.xml", |
||||
deps = [ |
||||
"@binder_transport_android_helper//io/grpc/binder/cpp:connection_helper", |
||||
], |
||||
) |
||||
|
||||
android_binary( |
||||
name = "app", |
||||
manifest = "AndroidManifest.xml", |
||||
deps = [ |
||||
":activity", |
||||
], |
||||
) |
@ -1,13 +0,0 @@ |
||||
package io.grpc.binder.cpp.exampleserver; |
||||
|
||||
import android.app.Application; |
||||
|
||||
public class ButtonPressHandler { |
||||
static { |
||||
System.loadLibrary("app"); |
||||
} |
||||
|
||||
public String onPressed(Application application) { |
||||
return "Server Button Pressed"; |
||||
} |
||||
} |
@ -1,26 +0,0 @@ |
||||
package io.grpc.binder.cpp.exampleserver; |
||||
|
||||
import android.app.Service; |
||||
import android.content.Intent; |
||||
import android.os.IBinder; |
||||
import android.content.Context; |
||||
import io.grpc.binder.cpp.GrpcCppServerBuilder; |
||||
|
||||
/** Exposes gRPC services running in the main process */ |
||||
public final class ExportedEndpointService extends Service { |
||||
static { |
||||
System.loadLibrary("app"); |
||||
} |
||||
|
||||
public ExportedEndpointService() { |
||||
init_grpc_server(this); |
||||
} |
||||
|
||||
@Override |
||||
public IBinder onBind(Intent intent) { |
||||
// The argument should match the URI passed into grpc::ServerBuilder::AddListeningPort
|
||||
return GrpcCppServerBuilder.GetEndpointBinder("binder:example.service"); |
||||
} |
||||
|
||||
public native void init_grpc_server(Context context); |
||||
} |
@ -1,27 +0,0 @@ |
||||
package io.grpc.binder.cpp.exampleserver; |
||||
|
||||
import android.app.Activity; |
||||
import android.os.Bundle; |
||||
import android.util.Log; |
||||
import android.widget.Button; |
||||
import android.widget.TextView; |
||||
import io.grpc.binder.cpp.exampleserver.R; |
||||
|
||||
/** Main class for the example app. */ |
||||
public class MainActivity extends Activity { |
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
Log.v("Example", "hello, world"); |
||||
|
||||
setContentView(R.layout.activity_main); |
||||
|
||||
Button clickMeButton = findViewById(R.id.clickMeButton); |
||||
TextView exampleTextView = findViewById(R.id.exampleTextView); |
||||
|
||||
ButtonPressHandler h = new ButtonPressHandler(); |
||||
|
||||
clickMeButton.setOnClickListener( |
||||
v -> exampleTextView.setText(h.onPressed(getApplication()))); |
||||
} |
||||
} |
@ -1,83 +0,0 @@ |
||||
// 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 "examples/protos/helloworld.grpc.pb.h" |
||||
#include "examples/protos/helloworld.pb.h" |
||||
|
||||
#include <grpcpp/create_channel_binder.h> |
||||
#include <grpcpp/grpcpp.h> |
||||
#include <grpcpp/security/binder_credentials.h> |
||||
#include <grpcpp/security/binder_security_policy.h> |
||||
|
||||
namespace { |
||||
class GreeterService : public helloworld::Greeter::Service { |
||||
public: |
||||
grpc::Status SayHello(grpc::ServerContext*, |
||||
const helloworld::HelloRequest* request, |
||||
helloworld::HelloReply* response) override { |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoServer", "Line number %d", |
||||
__LINE__); |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoServer", "Got hello request: %s", |
||||
request->name().c_str()); |
||||
response->set_message("Hi, " + request->name()); |
||||
return grpc::Status::OK; |
||||
} |
||||
}; |
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL |
||||
Java_io_grpc_binder_cpp_exampleserver_ExportedEndpointService_init_1grpc_1server( |
||||
JNIEnv* env, jobject /*this*/, jobject context) { |
||||
// Lower the gRPC logging level, here it is just for demo and debugging
|
||||
// purpose.
|
||||
setenv("GRPC_VERBOSITY", "INFO", true); |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoServer", "Line number %d", |
||||
__LINE__); |
||||
static std::unique_ptr<grpc::Server> server = nullptr; |
||||
|
||||
if (server != nullptr) { |
||||
// Already initiated
|
||||
return; |
||||
} |
||||
|
||||
if (grpc::experimental::InitializeBinderChannelJavaClass(env)) { |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoServer", |
||||
"InitializeBinderChannelJavaClass succeed"); |
||||
} else { |
||||
__android_log_print(ANDROID_LOG_INFO, "DemoServer", |
||||
"InitializeBinderChannelJavaClass failed"); |
||||
} |
||||
|
||||
static GreeterService service; |
||||
grpc::ServerBuilder server_builder; |
||||
server_builder.RegisterService(&service); |
||||
|
||||
JavaVM* jvm; |
||||
{ |
||||
jint result = env->GetJavaVM(&jvm); |
||||
assert(result == 0); |
||||
} |
||||
server_builder.AddListeningPort( |
||||
"binder:example.service", |
||||
grpc::experimental::BinderServerCredentials( |
||||
std::make_shared< |
||||
grpc::experimental::binder::SameSignatureSecurityPolicy>( |
||||
jvm, context))); |
||||
|
||||
server = server_builder.BuildAndStart(); |
||||
} |
@ -1,24 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:padding="16dp" |
||||
android:orientation="vertical" |
||||
android:gravity="center_vertical" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<TextView |
||||
android:id="@+id/exampleTextView" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:textSize="32dp" |
||||
android:text="@string/thinking_face"/> |
||||
|
||||
<Button |
||||
android:id="@+id/clickMeButton" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:layout_marginTop="16dp" |
||||
android:text="@string/click_me_button"/> |
||||
</LinearLayout> |
@ -1,5 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<string name="click_me_button">Run example</string> |
||||
<string name="thinking_face">🤔</string> |
||||
</resources> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue