mirror of https://github.com/grpc/grpc.git
parent
49d63f686a
commit
4abd199841
49 changed files with 1 additions and 3839 deletions
@ -1,82 +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.
|
||||
|
||||
#ifndef GRPCPP_SECURITY_BINDER_SECURITY_POLICY_H |
||||
#define GRPCPP_SECURITY_BINDER_SECURITY_POLICY_H |
||||
|
||||
#include <memory> |
||||
|
||||
#ifdef GPR_ANDROID |
||||
|
||||
#include <jni.h> |
||||
|
||||
#endif |
||||
|
||||
namespace grpc { |
||||
namespace experimental { |
||||
namespace binder { |
||||
|
||||
// EXPERIMENTAL Determinines if a connection is allowed to be
|
||||
// established on Android. See https://source.android.com/security/app-sandbox
|
||||
// for more info about UID.
|
||||
class SecurityPolicy { |
||||
public: |
||||
virtual ~SecurityPolicy() = default; |
||||
// Returns true if the UID is authorized to connect.
|
||||
// Must return the same value for the same inputs so callers can safely cache
|
||||
// the result.
|
||||
virtual bool IsAuthorized(int uid) = 0; |
||||
}; |
||||
|
||||
// EXPERIMENTAL Allows all connection. Anything on the Android device will be
|
||||
// able to connect, use with caution!
|
||||
class UntrustedSecurityPolicy : public SecurityPolicy { |
||||
public: |
||||
UntrustedSecurityPolicy(); |
||||
~UntrustedSecurityPolicy() override; |
||||
bool IsAuthorized(int uid) override; |
||||
}; |
||||
|
||||
// EXPERIMENTAL Only allows the connections from processes with the same UID. In
|
||||
// most cases this means "from the same APK".
|
||||
class InternalOnlySecurityPolicy : public SecurityPolicy { |
||||
public: |
||||
InternalOnlySecurityPolicy(); |
||||
~InternalOnlySecurityPolicy() override; |
||||
bool IsAuthorized(int uid) override; |
||||
}; |
||||
|
||||
#ifdef GPR_ANDROID |
||||
|
||||
// EXPERIMENTAL Only allows the connections from the APK that have the same
|
||||
// signature.
|
||||
class SameSignatureSecurityPolicy : public SecurityPolicy { |
||||
public: |
||||
// `context` is required for getting PackageManager Java class
|
||||
SameSignatureSecurityPolicy(JavaVM* jvm, jobject context); |
||||
~SameSignatureSecurityPolicy() override; |
||||
bool IsAuthorized(int uid) override; |
||||
|
||||
private: |
||||
JavaVM* jvm_; |
||||
jobject context_; |
||||
}; |
||||
|
||||
#endif |
||||
|
||||
} // namespace binder
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCPP_SECURITY_BINDER_SECURITY_POLICY_H
|
@ -1,10 +0,0 @@ |
||||
# Binder transport for cross process IPC on Android |
||||
|
||||
EXPERIMENTAL. API stability not guaranteed. |
||||
|
||||
This transport implements |
||||
[BinderChannel for native cross-process communication on Android](https://github.com/grpc/proposal/blob/master/L73-java-binderchannel.md) and enables C++/Java cross-process communication on Android with gRPC. |
||||
|
||||
Tests: https://github.com/grpc/grpc/tree/master/test/core/transport/binder/ |
||||
|
||||
Example apps: https://github.com/grpc/grpc/tree/master/examples/android/binder/java/io/grpc/binder/cpp |
@ -1,42 +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.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_IMPL_H |
||||
#define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_IMPL_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
#include <grpcpp/security/binder_security_policy.h> |
||||
|
||||
#include "src/core/ext/transport/binder/wire_format/binder.h" |
||||
#include "src/core/lib/channel/channel_args.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
// Creates a GRPC_CLIENT_DIRECT_CHANNEL channel from endpoint binder
|
||||
// At this moment this is only used for testing.
|
||||
grpc_channel* CreateDirectBinderChannelImplForTesting( |
||||
std::unique_ptr<grpc_binder::Binder> endpoint_binder, |
||||
const grpc_channel_args* args, |
||||
std::shared_ptr<grpc::experimental::binder::SecurityPolicy> |
||||
security_policy); |
||||
|
||||
// Creates a GRPC_CLIENT_CHANNEL channel
|
||||
grpc_channel* CreateClientBinderChannelImpl(std::string target, |
||||
const grpc_channel_args* args); |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_CLIENT_CHANNEL_CREATE_IMPL_H
|
@ -1,69 +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 "src/core/ext/transport/binder/client/connection_id_generator.h" |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#ifndef GRPC_NO_BINDER |
||||
|
||||
#include "absl/log/check.h" |
||||
#include "absl/strings/str_cat.h" |
||||
|
||||
namespace { |
||||
// Make sure `s` does not contain characters other than numbers, alphabets,
|
||||
// period and underscore
|
||||
std::string Normalize(absl::string_view str_view) { |
||||
std::string s = std::string(str_view); |
||||
for (size_t i = 0; i < s.length(); i++) { |
||||
if (!isalnum(s[i]) && s[i] != '.') { |
||||
s[i] = '_'; |
||||
} |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
// Remove prefix of the string if the string is longer than len
|
||||
std::string StripToLength(const std::string& s, size_t len) { |
||||
if (s.length() > len) { |
||||
return s.substr(s.length() - len, len); |
||||
} |
||||
return s; |
||||
} |
||||
} // namespace
|
||||
|
||||
namespace grpc_binder { |
||||
|
||||
std::string ConnectionIdGenerator::Generate(absl::string_view uri) { |
||||
// reserve some room for serial number
|
||||
const size_t kReserveForNumbers = 15; |
||||
std::string s = |
||||
StripToLength(Normalize(uri), kPathLengthLimit - kReserveForNumbers); |
||||
std::string ret; |
||||
{ |
||||
grpc_core::MutexLock l(&m_); |
||||
// Insert a hyphen before serial number
|
||||
ret = absl::StrCat(s, "-", ++count_); |
||||
} |
||||
CHECK_LT(ret.length(), kPathLengthLimit); |
||||
return ret; |
||||
} |
||||
|
||||
ConnectionIdGenerator* GetConnectionIdGenerator() { |
||||
static ConnectionIdGenerator* cig = new ConnectionIdGenerator(); |
||||
return cig; |
||||
} |
||||
|
||||
} // namespace grpc_binder
|
||||
#endif |
@ -1,30 +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. |
||||
|
||||
# copybara: Import internal android_library rule here |
||||
|
||||
licenses(["notice"]) |
||||
|
||||
android_library( |
||||
name = "connection_helper", |
||||
srcs = [ |
||||
"GrpcBinderConnection.java", |
||||
"GrpcCppServerBuilder.java", |
||||
"NativeConnectionHelper.java", |
||||
], |
||||
visibility = ["//visibility:public"], |
||||
deps = [ |
||||
# copybara: Add proguard dependency here |
||||
], |
||||
) |
@ -1,104 +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.
|
||||
|
||||
package io.grpc.binder.cpp; |
||||
|
||||
import static android.content.Intent.URI_ANDROID_APP_SCHEME; |
||||
import static android.content.Intent.URI_INTENT_SCHEME; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.ComponentName; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.content.ServiceConnection; |
||||
import android.os.IBinder; |
||||
import android.util.Log; |
||||
import java.net.URISyntaxException; |
||||
|
||||
/* 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; |
||||
|
||||
// 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. 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. mConnId = " + mConnId); |
||||
} |
||||
|
||||
public void tryConnect(String pkg, String cls, String action_name) { |
||||
Intent intent = new Intent(action_name); |
||||
ComponentName compName = new ComponentName(pkg, cls); |
||||
intent.setComponent(compName); |
||||
tryConnect(intent); |
||||
} |
||||
|
||||
@TargetApi(22) |
||||
public void tryConnect(String uri) { |
||||
// Try connect with an URI that can be parsed as intent.
|
||||
try { |
||||
tryConnect(Intent.parseUri(uri, URI_ANDROID_APP_SCHEME | URI_INTENT_SCHEME)); |
||||
} catch (URISyntaxException e) { |
||||
Log.e(logTag, "Unable to parse the Uri: " + uri); |
||||
} |
||||
} |
||||
|
||||
private void tryConnect(Intent intent) { |
||||
synchronized (this) { |
||||
// Will return true if the system is in the process of bringing up a service that your client
|
||||
// has permission to bind to; false if the system couldn't find the service or if your client
|
||||
// doesn't have permission to bind to it
|
||||
boolean result = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); |
||||
if (result) { |
||||
Log.e(logTag, "bindService returns ok"); |
||||
} else { |
||||
Log.e( |
||||
logTag, |
||||
"bindService failed. Maybe the system couldn't find the service or the" |
||||
+ " client doesn't have permission to bind to it."); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Calls a function defined in endpoint_binder_pool.cc
|
||||
private static native void notifyConnected(String connId, IBinder service); |
||||
} |
@ -1,40 +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.
|
||||
|
||||
package io.grpc.binder.cpp; |
||||
|
||||
import android.os.IBinder; |
||||
import android.util.Log; |
||||
|
||||
/* EXPERIMENTAL. Provides a interface to get endpoint binder from C++ */ |
||||
public class GrpcCppServerBuilder { |
||||
private static final String logTag = "GrpcCppServerBuilder"; |
||||
|
||||
public static IBinder GetEndpointBinder(String uri) { |
||||
String scheme = "binder:"; |
||||
if (uri.startsWith(scheme)) { |
||||
String path = uri.substring(scheme.length()); |
||||
// TODO(mingcl): Consider if we would like to make sure the path only contain valid
|
||||
// characters here
|
||||
IBinder ibinder = GetEndpointBinderInternal(path); |
||||
Log.e(logTag, "Returning binder=" + ibinder + " for URI=" + uri); |
||||
return ibinder; |
||||
} else { |
||||
Log.e(logTag, "URI " + uri + " does not start with 'binder:'"); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
private static native IBinder GetEndpointBinderInternal(String conn_id); |
||||
} |
@ -1,71 +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.
|
||||
|
||||
package io.grpc.binder.cpp; |
||||
|
||||
import android.content.Context; |
||||
import android.content.pm.PackageManager; |
||||
import android.os.Parcel; |
||||
import android.util.Log; |
||||
// copybara: Import proguard UsedByNative annotation here
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* This class will be invoked by gRPC binder transport internal implementation (from |
||||
* src/core/ext/transport/binder/client/jni_utils.cc) to perform operations that are only possible |
||||
* in Java |
||||
*/ |
||||
// copybara: Add @UsedByNative("jni_utils.cc")
|
||||
final class NativeConnectionHelper { |
||||
// Maps connection id to GrpcBinderConnection instances
|
||||
static Map<String, GrpcBinderConnection> connectionIdToGrpcBinderConnectionMap = new HashMap<>(); |
||||
|
||||
// copybara: Add @UsedByNative("jni_utils.cc")
|
||||
static void tryEstablishConnection( |
||||
Context context, String pkg, String cls, String actionName, String connId) { |
||||
// TODO(mingcl): Assert that connId is unique
|
||||
connectionIdToGrpcBinderConnectionMap.put(connId, new GrpcBinderConnection(context, connId)); |
||||
connectionIdToGrpcBinderConnectionMap.get(connId).tryConnect(pkg, cls, actionName); |
||||
} |
||||
|
||||
// copybara: Add @UsedByNative("jni_utils.cc")
|
||||
static void tryEstablishConnectionWithUri(Context context, String uri, String connId) { |
||||
// TODO(mingcl): Assert that connId is unique
|
||||
connectionIdToGrpcBinderConnectionMap.put(connId, new GrpcBinderConnection(context, connId)); |
||||
connectionIdToGrpcBinderConnectionMap.get(connId).tryConnect(uri); |
||||
} |
||||
|
||||
// Returns true if the packages signature of the 2 UIDs match.
|
||||
// `context` is used to get PackageManager.
|
||||
// Suppress unnecessary internal warnings related to checkSignatures compatibility issue.
|
||||
// BinderTransport code is only used on newer Android platform versions so this is fine.
|
||||
@SuppressWarnings("CheckSignatures") |
||||
// copybara: Add @UsedByNative("jni_utils.cc")
|
||||
static boolean isSignatureMatch(Context context, int uid1, int uid2) { |
||||
int result = context.getPackageManager().checkSignatures(uid1, uid2); |
||||
if (result == PackageManager.SIGNATURE_MATCH) { |
||||
return true; |
||||
} |
||||
Log.e( |
||||
"NativeConnectionHelper", |
||||
"Signatures does not match. checkSignature return value = " + result); |
||||
return false; |
||||
} |
||||
|
||||
// copybara: Add @UsedByNative("jni_utils.cc")
|
||||
static Parcel getEmptyParcel() { |
||||
return Parcel.obtain(); |
||||
} |
||||
} |
@ -1,40 +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.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_SECURITY_POLICY_SECURITY_POLICY_H |
||||
#define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_SECURITY_POLICY_SECURITY_POLICY_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
namespace grpc { |
||||
namespace experimental { |
||||
namespace binder { |
||||
|
||||
// This interface is for determining if a connection is allowed to be
|
||||
// established on Android. See https://source.android.com/security/app-sandbox
|
||||
// for more info about UID.
|
||||
class SecurityPolicy { |
||||
public: |
||||
virtual ~SecurityPolicy() = default; |
||||
// Returns true if the UID is authorized to connect.
|
||||
// Must return the same value for the same inputs so callers can safely cache
|
||||
// the result.
|
||||
virtual bool IsAuthorized(int uid) = 0; |
||||
}; |
||||
|
||||
} // namespace binder
|
||||
} // namespace experimental
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_SECURITY_POLICY_SECURITY_POLICY_H
|
@ -1,117 +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.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_TRANSPORT_BINDER_STREAM_H |
||||
#define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_TRANSPORT_BINDER_STREAM_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/binder/transport/binder_transport.h" |
||||
|
||||
struct RecvInitialMetadataArgs { |
||||
grpc_binder_stream* stream; |
||||
grpc_binder_transport* transport; |
||||
int tx_code; |
||||
absl::StatusOr<grpc_binder::Metadata> initial_metadata; |
||||
}; |
||||
|
||||
struct RecvMessageArgs { |
||||
grpc_binder_stream* stream; |
||||
grpc_binder_transport* transport; |
||||
int tx_code; |
||||
absl::StatusOr<std::string> message; |
||||
}; |
||||
|
||||
struct RecvTrailingMetadataArgs { |
||||
grpc_binder_stream* stream; |
||||
grpc_binder_transport* transport; |
||||
int tx_code; |
||||
absl::StatusOr<grpc_binder::Metadata> trailing_metadata; |
||||
int status; |
||||
}; |
||||
|
||||
struct RegisterStreamArgs { |
||||
grpc_binder_stream* stream; |
||||
grpc_binder_transport* transport; |
||||
}; |
||||
|
||||
// TODO(mingcl): Figure out if we want to use class instead of struct here
|
||||
struct grpc_binder_stream { |
||||
// server_data will be null for client, and for server it will be whatever
|
||||
// passed in to the accept_stream_fn callback by client.
|
||||
grpc_binder_stream(grpc_binder_transport* t, grpc_stream_refcount* refcount, |
||||
const void* /*server_data*/, grpc_core::Arena* arena, |
||||
int tx_code, bool is_client) |
||||
: t(t), |
||||
refcount(refcount), |
||||
arena(arena), |
||||
tx_code(tx_code), |
||||
is_client(is_client), |
||||
is_closed(false) { |
||||
recv_initial_metadata_args.stream = this; |
||||
recv_initial_metadata_args.transport = t; |
||||
recv_message_args.stream = this; |
||||
recv_message_args.transport = t; |
||||
recv_trailing_metadata_args.stream = this; |
||||
recv_trailing_metadata_args.transport = t; |
||||
} |
||||
|
||||
~grpc_binder_stream() { |
||||
if (destroy_stream_then_closure != nullptr) { |
||||
grpc_core::ExecCtx::Run(DEBUG_LOCATION, destroy_stream_then_closure, |
||||
absl::OkStatus()); |
||||
} |
||||
} |
||||
|
||||
int GetTxCode() const { return tx_code; } |
||||
|
||||
grpc_binder_transport* t; |
||||
grpc_stream_refcount* refcount; |
||||
grpc_core::Arena* arena; |
||||
int tx_code; |
||||
const bool is_client; |
||||
bool is_closed; |
||||
|
||||
grpc_closure* destroy_stream_then_closure = nullptr; |
||||
grpc_closure destroy_stream; |
||||
|
||||
// The reason why this stream is cancelled and closed.
|
||||
grpc_error_handle cancel_self_error; |
||||
|
||||
grpc_closure recv_initial_metadata_closure; |
||||
RecvInitialMetadataArgs recv_initial_metadata_args; |
||||
grpc_closure recv_message_closure; |
||||
RecvMessageArgs recv_message_args; |
||||
grpc_closure recv_trailing_metadata_closure; |
||||
RecvTrailingMetadataArgs recv_trailing_metadata_args; |
||||
|
||||
grpc_closure register_stream_closure; |
||||
RegisterStreamArgs register_stream_args; |
||||
|
||||
// We store these fields passed from op batch, in order to access them through
|
||||
// grpc_binder_stream
|
||||
grpc_metadata_batch* recv_initial_metadata; |
||||
grpc_closure* recv_initial_metadata_ready = nullptr; |
||||
bool* trailing_metadata_available = nullptr; |
||||
absl::optional<grpc_core::SliceBuffer>* recv_message; |
||||
grpc_closure* recv_message_ready = nullptr; |
||||
bool* call_failed_before_recv_message = nullptr; |
||||
grpc_metadata_batch* recv_trailing_metadata; |
||||
grpc_closure* recv_trailing_metadata_finished = nullptr; |
||||
|
||||
bool trailing_metadata_sent = false; |
||||
bool need_to_call_trailing_metadata_callback = false; |
||||
}; |
||||
|
||||
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_TRANSPORT_BINDER_STREAM_H
|
@ -1,76 +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.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H |
||||
#define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#ifdef GPR_SUPPORT_BINDER_TRANSPORT |
||||
|
||||
#include "src/core/ext/transport/binder/utils/ndk_binder.h" |
||||
|
||||
namespace grpc_binder { |
||||
namespace ndk_util { |
||||
|
||||
///
|
||||
/// Represents one strong pointer to an AIBinder object.
|
||||
/// Copied from binder/ndk/include_cpp/android/binder_auto_utils.h
|
||||
///
|
||||
class SpAIBinder { |
||||
public: |
||||
SpAIBinder() : mBinder(nullptr) {} |
||||
explicit SpAIBinder(AIBinder* binder) : mBinder(binder) {} |
||||
SpAIBinder(std::nullptr_t) |
||||
: SpAIBinder() {} // NOLINT(google-explicit-constructor)
|
||||
SpAIBinder(const SpAIBinder& other) { *this = other; } |
||||
|
||||
~SpAIBinder() { set(nullptr); } |
||||
SpAIBinder& operator=(const SpAIBinder& other) { |
||||
if (this == &other) { |
||||
return *this; |
||||
} |
||||
AIBinder_incStrong(other.mBinder); |
||||
set(other.mBinder); |
||||
return *this; |
||||
} |
||||
|
||||
void set(AIBinder* binder) { |
||||
AIBinder* old = *const_cast<AIBinder* volatile*>(&mBinder); |
||||
if (old != nullptr) AIBinder_decStrong(old); |
||||
if (old != *const_cast<AIBinder* volatile*>(&mBinder)) { |
||||
__assert(__FILE__, __LINE__, "Race detected."); |
||||
} |
||||
mBinder = binder; |
||||
} |
||||
|
||||
AIBinder* get() const { return mBinder; } |
||||
AIBinder** getR() { return &mBinder; } |
||||
|
||||
bool operator!=(const SpAIBinder& rhs) const { return get() != rhs.get(); } |
||||
bool operator<(const SpAIBinder& rhs) const { return get() < rhs.get(); } |
||||
bool operator<=(const SpAIBinder& rhs) const { return get() <= rhs.get(); } |
||||
bool operator==(const SpAIBinder& rhs) const { return get() == rhs.get(); } |
||||
bool operator>(const SpAIBinder& rhs) const { return get() > rhs.get(); } |
||||
bool operator>=(const SpAIBinder& rhs) const { return get() >= rhs.get(); } |
||||
|
||||
private: |
||||
AIBinder* mBinder = nullptr; |
||||
}; |
||||
} // namespace ndk_util
|
||||
} // namespace grpc_binder
|
||||
|
||||
#endif |
||||
|
||||
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H
|
@ -1,107 +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.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_NDK_BINDER_H |
||||
#define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_NDK_BINDER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#ifdef GPR_SUPPORT_BINDER_TRANSPORT |
||||
|
||||
#include <assert.h> |
||||
#include <jni.h> |
||||
|
||||
#include <memory> |
||||
|
||||
// This file defines NdkBinder functions, variables, and types in
|
||||
// grpc_binder::ndk_util namespace. This allows us to dynamically load
|
||||
// libbinder_ndk at runtime, and make it possible to compile the code without
|
||||
// the library present at compile time.
|
||||
|
||||
// TODO(mingcl): Consider if we want to check API level and include NDK headers
|
||||
// normally if the level is high enough
|
||||
|
||||
namespace grpc_binder { |
||||
namespace ndk_util { |
||||
|
||||
struct AIBinder; |
||||
struct AParcel; |
||||
struct AIBinder_Class; |
||||
|
||||
// Only enum values used by the project is defined here
|
||||
enum { |
||||
FLAG_ONEWAY = 0x01, |
||||
}; |
||||
enum { |
||||
STATUS_OK = 0, |
||||
STATUS_UNKNOWN_ERROR = (-2147483647 - 1), |
||||
}; |
||||
|
||||
typedef int32_t binder_status_t; |
||||
typedef uint32_t binder_flags_t; |
||||
typedef uint32_t transaction_code_t; |
||||
|
||||
typedef bool (*AParcel_byteArrayAllocator)(void* arrayData, int32_t length, |
||||
int8_t** outBuffer); |
||||
typedef bool (*AParcel_stringAllocator)(void* stringData, int32_t length, |
||||
char** buffer); |
||||
typedef void* (*AIBinder_Class_onCreate)(void* args); |
||||
typedef void (*AIBinder_Class_onDestroy)(void* userData); |
||||
typedef binder_status_t (*AIBinder_Class_onTransact)(AIBinder* binder, |
||||
transaction_code_t code, |
||||
const AParcel* in, |
||||
AParcel* out); |
||||
|
||||
void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz); |
||||
void* AIBinder_getUserData(AIBinder* binder); |
||||
uid_t AIBinder_getCallingUid(); |
||||
AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder); |
||||
AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor, |
||||
AIBinder_Class_onCreate onCreate, |
||||
AIBinder_Class_onDestroy onDestroy, |
||||
AIBinder_Class_onTransact onTransact); |
||||
AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args); |
||||
bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz); |
||||
void AIBinder_incStrong(AIBinder* binder); |
||||
void AIBinder_decStrong(AIBinder* binder); |
||||
binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, |
||||
AParcel** in, AParcel** out, |
||||
binder_flags_t flags); |
||||
binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData, |
||||
AParcel_byteArrayAllocator allocator); |
||||
void AParcel_delete(AParcel* parcel); |
||||
int32_t AParcel_getDataSize(const AParcel* parcel); |
||||
binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value); |
||||
binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value); |
||||
binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder); |
||||
binder_status_t AParcel_writeString(AParcel* parcel, const char* string, |
||||
int32_t length); |
||||
binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value); |
||||
binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value); |
||||
binder_status_t AParcel_readString(const AParcel* parcel, void* stringData, |
||||
AParcel_stringAllocator allocator); |
||||
binder_status_t AParcel_readStrongBinder(const AParcel* parcel, |
||||
AIBinder** binder); |
||||
binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* arrayData, |
||||
int32_t length); |
||||
binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in); |
||||
jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder); |
||||
|
||||
} // namespace ndk_util
|
||||
|
||||
} // namespace grpc_binder
|
||||
|
||||
#endif // GPR_SUPPORT_BINDER_TRANSPORT
|
||||
|
||||
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_NDK_BINDER_H
|
@ -1,29 +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 <grpc/support/port_platform.h> |
||||
|
||||
#ifndef GRPC_NO_BINDER |
||||
|
||||
#include "src/core/ext/transport/binder/wire_format/binder_constants.h" |
||||
|
||||
ABSL_CONST_INIT const int FIRST_CALL_TRANSACTION = 0x00000001; |
||||
ABSL_CONST_INIT const int LAST_CALL_TRANSACTION = 0x00FFFFFF; |
||||
|
||||
namespace grpc_binder { |
||||
|
||||
ABSL_CONST_INIT const int kFirstCallId = FIRST_CALL_TRANSACTION + 1000; |
||||
|
||||
} // namespace grpc_binder
|
||||
#endif |
@ -1,33 +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 <grpc/support/port_platform.h> |
||||
|
||||
#ifndef GRPC_NO_BINDER |
||||
|
||||
#include "src/core/ext/transport/binder/wire_format/transaction.h" |
||||
|
||||
namespace grpc_binder { |
||||
|
||||
ABSL_CONST_INIT const int kFlagPrefix = 0x1; |
||||
ABSL_CONST_INIT const int kFlagMessageData = 0x2; |
||||
ABSL_CONST_INIT const int kFlagSuffix = 0x4; |
||||
ABSL_CONST_INIT const int kFlagOutOfBandClose = 0x8; |
||||
ABSL_CONST_INIT const int kFlagExpectSingleMessage = 0x10; |
||||
ABSL_CONST_INIT const int kFlagStatusDescription = 0x20; |
||||
ABSL_CONST_INIT const int kFlagMessageDataIsParcelable = 0x40; |
||||
ABSL_CONST_INIT const int kFlagMessageDataIsPartial = 0x80; |
||||
|
||||
} // namespace grpc_binder
|
||||
#endif |
@ -1,9 +0,0 @@ |
||||
Support for resolving the scheme used by binder transport implementation. |
||||
|
||||
The URI's authority is required to be empty. |
||||
|
||||
The path is used as the identifiers of endpoint binder objects and the length |
||||
limit of the identifier is the same as unix socket length limit. |
||||
|
||||
The length limit of the path should at least be 100 characters long. This is |
||||
guaranteed by `static_assert` in the implementation. |
@ -1,133 +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. |
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") |
||||
|
||||
licenses(["notice"]) |
||||
|
||||
grpc_package( |
||||
name = "test/core/transport/binder", |
||||
visibility = "tests", |
||||
) |
||||
|
||||
grpc_cc_library( |
||||
name = "mock_objects", |
||||
testonly = 1, |
||||
srcs = ["mock_objects.cc"], |
||||
hdrs = ["mock_objects.h"], |
||||
external_deps = [ |
||||
"absl/memory", |
||||
"gtest", |
||||
], |
||||
language = "C++", |
||||
deps = [ |
||||
"//:grpc++_binder", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "wire_writer_test", |
||||
srcs = ["wire_writer_test.cc"], |
||||
external_deps = [ |
||||
"absl/memory", |
||||
"gtest", |
||||
], |
||||
language = "C++", |
||||
tags = ["no_test_ios"], |
||||
uses_event_engine = False, |
||||
uses_polling = False, |
||||
deps = [ |
||||
":mock_objects", |
||||
"//:grpc++_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "wire_reader_test", |
||||
srcs = ["wire_reader_test.cc"], |
||||
external_deps = [ |
||||
"absl/memory", |
||||
"gtest", |
||||
], |
||||
language = "C++", |
||||
tags = ["no_test_ios"], |
||||
uses_event_engine = False, |
||||
uses_polling = False, |
||||
deps = [ |
||||
":mock_objects", |
||||
"//:grpc++_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "transport_stream_receiver_test", |
||||
srcs = ["transport_stream_receiver_test.cc"], |
||||
external_deps = [ |
||||
"absl/memory", |
||||
"gtest", |
||||
], |
||||
language = "C++", |
||||
tags = ["no_test_ios"], |
||||
uses_event_engine = False, |
||||
uses_polling = False, |
||||
deps = [ |
||||
"//:grpc++_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "binder_transport_test", |
||||
srcs = ["binder_transport_test.cc"], |
||||
external_deps = [ |
||||
"absl/memory", |
||||
"absl/strings", |
||||
"gtest", |
||||
], |
||||
language = "C++", |
||||
tags = [ |
||||
# To avoid `symbolizer buffer too small` warning of UBSAN |
||||
"noubsan", |
||||
"no_test_ios", |
||||
], |
||||
uses_event_engine = False, |
||||
uses_polling = False, |
||||
deps = [ |
||||
":mock_objects", |
||||
"//:grpc", |
||||
"//:grpc++_binder", |
||||
"//test/core/test_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++", |
||||
tags = ["no_test_ios"], |
||||
uses_event_engine = False, |
||||
uses_polling = False, |
||||
deps = [ |
||||
":mock_objects", |
||||
"//:grpc", |
||||
"//:grpc++_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
@ -1,119 +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. |
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") |
||||
|
||||
licenses(["notice"]) |
||||
|
||||
grpc_package( |
||||
name = "test/core/transport/binder/end2end", |
||||
visibility = "tests", |
||||
) |
||||
|
||||
grpc_cc_library( |
||||
name = "fake_binder", |
||||
testonly = 1, |
||||
srcs = ["fake_binder.cc"], |
||||
hdrs = ["fake_binder.h"], |
||||
external_deps = [ |
||||
"absl/log:log", |
||||
"absl/memory", |
||||
"absl/random", |
||||
"absl/strings", |
||||
"absl/strings:str_format", |
||||
"absl/time", |
||||
"absl/types:variant", |
||||
], |
||||
deps = [ |
||||
"//:gpr", |
||||
"//:grpc++_binder", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "fake_binder_test", |
||||
srcs = ["fake_binder_test.cc"], |
||||
external_deps = [ |
||||
"absl/strings", |
||||
"absl/time", |
||||
"gtest", |
||||
], |
||||
language = "C++", |
||||
tags = ["no_test_ios"], |
||||
uses_event_engine = False, |
||||
uses_polling = False, |
||||
deps = [ |
||||
":fake_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_library( |
||||
name = "end2end_binder_channel", |
||||
testonly = 1, |
||||
srcs = ["testing_channel_create.cc"], |
||||
hdrs = ["testing_channel_create.h"], |
||||
external_deps = ["absl/log:check"], |
||||
deps = [ |
||||
":fake_binder", |
||||
"//:grpc++_base", |
||||
"//:grpc++_binder", |
||||
"//:grpc_base", |
||||
"//src/core:channel_args", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "end2end_binder_transport_test", |
||||
srcs = ["end2end_binder_transport_test.cc"], |
||||
external_deps = [ |
||||
"absl/memory", |
||||
"absl/time", |
||||
"gtest", |
||||
], |
||||
flaky = True, |
||||
language = "C++", |
||||
tags = [ |
||||
# Flaky on windows |
||||
"no_windows", |
||||
"no_mac", |
||||
"no_test_ios", |
||||
|
||||
# Known race between stream creation and cancellation |
||||
"notsan", |
||||
], |
||||
deps = [ |
||||
":end2end_binder_channel", |
||||
":fake_binder", |
||||
"//:grpc++_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
"//test/cpp/end2end:test_service_impl", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_test( |
||||
name = "binder_server_test", |
||||
srcs = ["binder_server_test.cc"], |
||||
external_deps = [ |
||||
"gtest", |
||||
], |
||||
tags = ["no_test_ios"], |
||||
deps = [ |
||||
"//:grpc++", |
||||
"//:grpc++_binder", |
||||
"//test/core/test_util:grpc_test_util", |
||||
"//test/core/transport/binder/end2end:fake_binder", |
||||
"//test/cpp/end2end:test_service_impl", |
||||
], |
||||
) |
@ -1,101 +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. |
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_package", "grpc_proto_library") |
||||
load("//test/core/test_util:grpc_fuzzer.bzl", "grpc_proto_fuzzer") |
||||
|
||||
grpc_package( |
||||
name = "test/core/transport/binder/end2end/fuzzers", |
||||
features = [ |
||||
"layering_check", |
||||
], |
||||
) |
||||
|
||||
licenses(["notice"]) |
||||
|
||||
# Protobuf messages for generating inputs. We manually define proto |
||||
# library rule here so the same proto file can be shared between multiple |
||||
# grpc_proto_fuzzer targets |
||||
grpc_proto_library( |
||||
name = "binder_transport_fuzzer_proto", |
||||
srcs = ["binder_transport_fuzzer.proto"], |
||||
) |
||||
|
||||
grpc_cc_library( |
||||
name = "fuzzer_utils", |
||||
srcs = ["fuzzer_utils.cc"], |
||||
external_deps = [ |
||||
"absl/log:check", |
||||
"absl/log:log", |
||||
], |
||||
language = "c++", |
||||
public_hdrs = ["fuzzer_utils.h"], |
||||
deps = [ |
||||
"binder_transport_fuzzer_proto", |
||||
"//:gpr", |
||||
"//:grpc++", |
||||
"//:grpc++_base", |
||||
"//:grpc_base", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
||||
|
||||
grpc_proto_fuzzer( |
||||
name = "binder_transport_client_fuzzer", |
||||
srcs = [ |
||||
"client_fuzzer.cc", |
||||
], |
||||
corpus = "binder_transport_client_fuzzer_corpus", |
||||
external_deps = ["absl/log:check"], |
||||
owner = "binder", |
||||
proto = "client.proto", |
||||
tags = [ |
||||
"no_mac", |
||||
"no_windows", |
||||
], |
||||
deps = [ |
||||
"binder_transport_fuzzer_proto", |
||||
":fuzzer_utils", |
||||
"//:gpr", |
||||
"//:grpc++", |
||||
"//:grpc++_base", |
||||
"//:grpc_base", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
||||
|
||||
grpc_proto_fuzzer( |
||||
name = "binder_transport_server_fuzzer", |
||||
srcs = [ |
||||
"server_fuzzer.cc", |
||||
], |
||||
corpus = "binder_transport_server_fuzzer_corpus", |
||||
external_deps = ["absl/log:check"], |
||||
owner = "binder", |
||||
proto = "server.proto", |
||||
tags = [ |
||||
"no_mac", |
||||
"no_windows", |
||||
], |
||||
deps = [ |
||||
"binder_transport_fuzzer_proto", |
||||
":fuzzer_utils", |
||||
"//:gpr", |
||||
"//:grpc++", |
||||
"//:grpc++_base", |
||||
"//:grpc_base", |
||||
"//src/core:slice", |
||||
"//test/core/test_util:grpc_test_util", |
||||
], |
||||
) |
@ -1,81 +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. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package binder_transport_fuzzer; |
||||
|
||||
message Binder {} |
||||
|
||||
message Value { |
||||
oneof data_type { |
||||
int32 i32 = 1; |
||||
int64 i64 = 2; |
||||
bytes byte_array = 3; |
||||
// Strings in Parcel could also contain non UTF-8 data so we use bytes |
||||
// to represent string here |
||||
bytes str = 4; |
||||
Binder binder = 5; |
||||
} |
||||
} |
||||
|
||||
message Parcel { |
||||
repeated Value values = 1; |
||||
|
||||
// Simulates the return value of AParcel_getDataSize |
||||
// (The value generated by protobuf libprotobuf-mutator might not always make sense |
||||
// but the transport implementation should handle that) |
||||
int32 data_size = 2; |
||||
} |
||||
|
||||
enum TransactionCode { |
||||
INVALID = 0; |
||||
SETUP_TRANSPORT = 1; |
||||
SHUTDOWN_TRANSPORT = 2; |
||||
ACKNOWLEDGE_BYTES = 3; |
||||
PING = 4; |
||||
PING_RESPONSE = 5; |
||||
} |
||||
|
||||
message Transaction { |
||||
TransactionCode code = 1; |
||||
int32 uid = 2; |
||||
Parcel parcel = 3; |
||||
} |
||||
|
||||
// Special parcel that used for setting up transport. |
||||
// TODO(mingcl): Consider also fuzzing the setup transport code path |
||||
message SetupTransportParcel { |
||||
int32 version = 1; |
||||
|
||||
// Simulates the return value of AParcel_getDataSize |
||||
// (The value generated by protobuf libprotobuf-mutator might not always make sense |
||||
// but the transport implementation should handle that) |
||||
int32 data_size = 2; |
||||
} |
||||
|
||||
message SetupTransportTransaction { |
||||
int32 uid = 1; |
||||
SetupTransportParcel parcel = 2; |
||||
} |
||||
|
||||
message IncomingParcels { |
||||
SetupTransportTransaction setup_transport_transaction = 1; |
||||
repeated Transaction transactions = 2; |
||||
} |
||||
|
||||
message Input { |
||||
IncomingParcels incoming_parcels = 1; |
||||
} |
||||
|
@ -1,17 +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. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package binder_transport_fuzzer; |
@ -1,157 +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 "test/core/transport/binder/end2end/fuzzers/fuzzer_utils.h" |
||||
|
||||
#include "absl/log/check.h" |
||||
#include "absl/log/log.h" |
||||
|
||||
namespace grpc_binder { |
||||
namespace fuzzing { |
||||
|
||||
namespace { |
||||
|
||||
std::thread* g_fuzzing_thread = nullptr; |
||||
|
||||
template <typename... Args> |
||||
void CreateFuzzingThread(Args&&... args) { |
||||
CHECK_EQ(g_fuzzing_thread, nullptr); |
||||
g_fuzzing_thread = new std::thread(std::forward<Args>(args)...); |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
void JoinFuzzingThread() { |
||||
if (g_fuzzing_thread) { |
||||
g_fuzzing_thread->join(); |
||||
delete g_fuzzing_thread; |
||||
g_fuzzing_thread = nullptr; |
||||
} |
||||
} |
||||
|
||||
int32_t ReadableParcelForFuzzing::GetDataSize() const { |
||||
return parcel_data_size_; |
||||
} |
||||
|
||||
absl::Status ReadableParcelForFuzzing::ReadInt32(int32_t* data) { |
||||
if (consumed_data_size_ >= kParcelDataSizeLimit) { |
||||
return absl::InternalError("Parcel size limit exceeds"); |
||||
} |
||||
if (values_.empty() || !values_.front().has_i32()) { |
||||
return absl::InternalError("error"); |
||||
} |
||||
*data = values_.front().i32(); |
||||
values_.pop(); |
||||
consumed_data_size_ += sizeof(int32_t); |
||||
return absl::OkStatus(); |
||||
} |
||||
|
||||
absl::Status ReadableParcelForFuzzing::ReadInt64(int64_t* data) { |
||||
if (consumed_data_size_ >= kParcelDataSizeLimit) { |
||||
return absl::InternalError("Parcel size limit exceeds"); |
||||
} |
||||
if (values_.empty() || !values_.front().has_i64()) { |
||||
return absl::InternalError("error"); |
||||
} |
||||
*data = values_.front().i64(); |
||||
values_.pop(); |
||||
consumed_data_size_ += sizeof(int64_t); |
||||
return absl::OkStatus(); |
||||
} |
||||
|
||||
absl::Status ReadableParcelForFuzzing::ReadBinder( |
||||
std::unique_ptr<Binder>* binder) { |
||||
if (consumed_data_size_ >= kParcelDataSizeLimit) { |
||||
return absl::InternalError("Parcel size limit exceeds"); |
||||
} |
||||
if (values_.empty() || !values_.front().has_binder()) { |
||||
return absl::InternalError("error"); |
||||
} |
||||
*binder = std::make_unique<BinderForFuzzing>(); |
||||
values_.pop(); |
||||
consumed_data_size_ += sizeof(void*); |
||||
return absl::OkStatus(); |
||||
} |
||||
|
||||
absl::Status ReadableParcelForFuzzing::ReadByteArray(std::string* data) { |
||||
if (consumed_data_size_ >= kParcelDataSizeLimit) { |
||||
return absl::InternalError("Parcel size limit exceeds"); |
||||
} |
||||
if (values_.empty() || !values_.front().has_byte_array()) { |
||||
return absl::InternalError("error"); |
||||
} |
||||
*data = values_.front().byte_array(); |
||||
values_.pop(); |
||||
consumed_data_size_ += data->size(); |
||||
return absl::OkStatus(); |
||||
} |
||||
|
||||
absl::Status ReadableParcelForFuzzing::ReadString(std::string* data) { |
||||
if (consumed_data_size_ >= kParcelDataSizeLimit) { |
||||
return absl::InternalError("Parcel size limit exceeds"); |
||||
} |
||||
if (values_.empty() || !values_.front().has_str()) { |
||||
return absl::InternalError("error"); |
||||
} |
||||
*data = values_.front().str(); |
||||
values_.pop(); |
||||
consumed_data_size_ += data->size(); |
||||
return absl::OkStatus(); |
||||
} |
||||
|
||||
void FuzzingLoop( |
||||
binder_transport_fuzzer::IncomingParcels incoming_parcels, |
||||
grpc_core::RefCountedPtr<grpc_binder::WireReader> wire_reader_ref, |
||||
grpc_binder::TransactionReceiver::OnTransactCb callback) { |
||||
{ |
||||
// Send SETUP_TRANSPORT request.
|
||||
std::unique_ptr<grpc_binder::ReadableParcel> parcel = |
||||
std::make_unique<ReadableParcelForFuzzing>( |
||||
incoming_parcels.setup_transport_transaction().parcel()); |
||||
callback(static_cast<transaction_code_t>( |
||||
grpc_binder::BinderTransportTxCode::SETUP_TRANSPORT), |
||||
parcel.get(), |
||||
/*uid=*/incoming_parcels.setup_transport_transaction().uid()) |
||||
.IgnoreError(); |
||||
} |
||||
for (const auto& tx_iter : incoming_parcels.transactions()) { |
||||
transaction_code_t tx_code = tx_iter.code(); |
||||
std::unique_ptr<grpc_binder::ReadableParcel> parcel = |
||||
std::make_unique<ReadableParcelForFuzzing>(tx_iter.parcel()); |
||||
callback(tx_code, parcel.get(), |
||||
/*uid=*/tx_iter.uid()) |
||||
.IgnoreError(); |
||||
} |
||||
wire_reader_ref = nullptr; |
||||
} |
||||
|
||||
TransactionReceiverForFuzzing::TransactionReceiverForFuzzing( |
||||
binder_transport_fuzzer::IncomingParcels incoming_parcels, |
||||
grpc_core::RefCountedPtr<WireReader> wire_reader_ref, |
||||
TransactionReceiver::OnTransactCb cb) { |
||||
LOG(INFO) << "Construct TransactionReceiverForFuzzing"; |
||||
CreateFuzzingThread(FuzzingLoop, std::move(incoming_parcels), |
||||
std::move(wire_reader_ref), std::move(cb)); |
||||
} |
||||
|
||||
std::unique_ptr<TransactionReceiver> BinderForFuzzing::ConstructTxReceiver( |
||||
grpc_core::RefCountedPtr<WireReader> wire_reader_ref, |
||||
TransactionReceiver::OnTransactCb cb) const { |
||||
auto tx_receiver = std::make_unique<TransactionReceiverForFuzzing>( |
||||
incoming_parcels_, wire_reader_ref, cb); |
||||
return tx_receiver; |
||||
} |
||||
|
||||
} // namespace fuzzing
|
||||
} // namespace grpc_binder
|
@ -1,17 +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. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package binder_transport_fuzzer; |
@ -1,55 +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 "test/core/transport/binder/mock_objects.h" |
||||
|
||||
#include <memory> |
||||
|
||||
#include "absl/memory/memory.h" |
||||
|
||||
namespace grpc_binder { |
||||
|
||||
using ::testing::Return; |
||||
|
||||
MockReadableParcel::MockReadableParcel() { |
||||
ON_CALL(*this, ReadBinder).WillByDefault([](std::unique_ptr<Binder>* binder) { |
||||
*binder = std::make_unique<MockBinder>(); |
||||
return absl::OkStatus(); |
||||
}); |
||||
ON_CALL(*this, ReadInt32).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, ReadByteArray).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, ReadString).WillByDefault(Return(absl::OkStatus())); |
||||
} |
||||
|
||||
MockWritableParcel::MockWritableParcel() { |
||||
ON_CALL(*this, WriteInt32).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, WriteBinder).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, WriteString).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, WriteByteArray).WillByDefault(Return(absl::OkStatus())); |
||||
} |
||||
|
||||
MockBinder::MockBinder() { |
||||
ON_CALL(*this, PrepareTransaction).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, Transact).WillByDefault(Return(absl::OkStatus())); |
||||
ON_CALL(*this, GetWritableParcel).WillByDefault(Return(&mock_input_)); |
||||
ON_CALL(*this, ConstructTxReceiver) |
||||
.WillByDefault( |
||||
[this](grpc_core::RefCountedPtr<WireReader> /*wire_reader_ref*/, |
||||
TransactionReceiver::OnTransactCb cb) { |
||||
return std::make_unique<MockTransactionReceiver>( |
||||
cb, BinderTransportTxCode::SETUP_TRANSPORT, &mock_output_); |
||||
}); |
||||
} |
||||
|
||||
} // namespace grpc_binder
|
@ -1,121 +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.
|
||||
|
||||
#ifndef GRPC_TEST_CORE_TRANSPORT_BINDER_MOCK_OBJECTS_H |
||||
#define GRPC_TEST_CORE_TRANSPORT_BINDER_MOCK_OBJECTS_H |
||||
|
||||
#include <gmock/gmock.h> |
||||
|
||||
#include "src/core/ext/transport/binder/utils/transport_stream_receiver.h" |
||||
#include "src/core/ext/transport/binder/wire_format/binder.h" |
||||
#include "src/core/ext/transport/binder/wire_format/binder_constants.h" |
||||
#include "src/core/ext/transport/binder/wire_format/wire_reader.h" |
||||
#include "src/core/ext/transport/binder/wire_format/wire_writer.h" |
||||
|
||||
namespace grpc_binder { |
||||
|
||||
class MockWritableParcel : public WritableParcel { |
||||
public: |
||||
MOCK_METHOD(int32_t, GetDataSize, (), (const, override)); |
||||
MOCK_METHOD(absl::Status, WriteInt32, (int32_t), (override)); |
||||
MOCK_METHOD(absl::Status, WriteInt64, (int64_t), (override)); |
||||
MOCK_METHOD(absl::Status, WriteBinder, (HasRawBinder*), (override)); |
||||
MOCK_METHOD(absl::Status, WriteString, (absl::string_view), (override)); |
||||
MOCK_METHOD(absl::Status, WriteByteArray, (const int8_t*, int32_t), |
||||
(override)); |
||||
|
||||
MockWritableParcel(); |
||||
}; |
||||
|
||||
class MockReadableParcel : public ReadableParcel { |
||||
public: |
||||
MOCK_METHOD(int32_t, GetDataSize, (), (const, override)); |
||||
MOCK_METHOD(absl::Status, ReadInt32, (int32_t*), (override)); |
||||
MOCK_METHOD(absl::Status, ReadInt64, (int64_t*), (override)); |
||||
MOCK_METHOD(absl::Status, ReadBinder, (std::unique_ptr<Binder>*), (override)); |
||||
MOCK_METHOD(absl::Status, ReadByteArray, (std::string*), (override)); |
||||
MOCK_METHOD(absl::Status, ReadString, (std::string*), (override)); |
||||
|
||||
MockReadableParcel(); |
||||
}; |
||||
|
||||
class MockBinder : public Binder { |
||||
public: |
||||
MOCK_METHOD(void, Initialize, (), (override)); |
||||
MOCK_METHOD(absl::Status, PrepareTransaction, (), (override)); |
||||
MOCK_METHOD(absl::Status, Transact, (BinderTransportTxCode), (override)); |
||||
MOCK_METHOD(WritableParcel*, GetWritableParcel, (), (const, override)); |
||||
MOCK_METHOD(std::unique_ptr<TransactionReceiver>, ConstructTxReceiver, |
||||
(grpc_core::RefCountedPtr<WireReader>, |
||||
TransactionReceiver::OnTransactCb), |
||||
(const, override)); |
||||
MOCK_METHOD(void*, GetRawBinder, (), (override)); |
||||
|
||||
MockBinder(); |
||||
MockWritableParcel& GetWriter() { return mock_input_; } |
||||
MockReadableParcel& GetReader() { return mock_output_; } |
||||
|
||||
private: |
||||
MockWritableParcel mock_input_; |
||||
MockReadableParcel mock_output_; |
||||
}; |
||||
|
||||
// TODO(waynetu): Implement transaction injection later for more thorough
|
||||
// testing.
|
||||
class MockTransactionReceiver : public TransactionReceiver { |
||||
public: |
||||
explicit MockTransactionReceiver(OnTransactCb transact_cb, |
||||
BinderTransportTxCode code, |
||||
MockReadableParcel* output) { |
||||
if (code == BinderTransportTxCode::SETUP_TRANSPORT) { |
||||
EXPECT_CALL(*output, ReadInt32).WillOnce([](int32_t* version) { |
||||
*version = 1; |
||||
return absl::OkStatus(); |
||||
}); |
||||
} |
||||
transact_cb(static_cast<transaction_code_t>(code), output, /*uid=*/0) |
||||
.IgnoreError(); |
||||
} |
||||
|
||||
MOCK_METHOD(void*, GetRawBinder, (), (override)); |
||||
}; |
||||
|
||||
class MockWireWriter : public WireWriter { |
||||
public: |
||||
MOCK_METHOD(absl::Status, RpcCall, (std::unique_ptr<Transaction>), |
||||
(override)); |
||||
MOCK_METHOD(absl::Status, SendAck, (int64_t), (override)); |
||||
MOCK_METHOD(void, OnAckReceived, (int64_t), (override)); |
||||
}; |
||||
|
||||
class MockTransportStreamReceiver : public TransportStreamReceiver { |
||||
public: |
||||
MOCK_METHOD(void, RegisterRecvInitialMetadata, |
||||
(StreamIdentifier, InitialMetadataCallbackType), (override)); |
||||
MOCK_METHOD(void, RegisterRecvMessage, |
||||
(StreamIdentifier, MessageDataCallbackType), (override)); |
||||
MOCK_METHOD(void, RegisterRecvTrailingMetadata, |
||||
(StreamIdentifier, TrailingMetadataCallbackType), (override)); |
||||
MOCK_METHOD(void, NotifyRecvInitialMetadata, |
||||
(StreamIdentifier, absl::StatusOr<Metadata>), (override)); |
||||
MOCK_METHOD(void, NotifyRecvMessage, |
||||
(StreamIdentifier, absl::StatusOr<std::string>), (override)); |
||||
MOCK_METHOD(void, NotifyRecvTrailingMetadata, |
||||
(StreamIdentifier, absl::StatusOr<Metadata>, int), (override)); |
||||
MOCK_METHOD(void, CancelStream, (StreamIdentifier), (override)); |
||||
}; |
||||
|
||||
} // namespace grpc_binder
|
||||
|
||||
#endif // GRPC_TEST_CORE_TRANSPORT_BINDER_MOCK_OBJECTS_H
|
@ -1,40 +0,0 @@ |
||||
#!/usr/bin/env bash |
||||
# 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. |
||||
|
||||
set -ex |
||||
|
||||
echo $ANDROID_HOME |
||||
echo $ANDROID_NDK_HOME |
||||
|
||||
# Android platforms only works with Bazel >= 7.0 |
||||
export OVERRIDE_BAZEL_VERSION=7.3.1 |
||||
|
||||
python3 tools/run_tests/python_utils/bazel_report_helper.py --report_path bazel_binder_example_app |
||||
bazel_binder_example_app/bazel_wrapper \ |
||||
--bazelrc=tools/remote_build/include/test_locally_with_resultstore_results.bazelrc \ |
||||
build \ |
||||
--extra_toolchains=@androidndk//:all \ |
||||
--android_platforms=//bazel/platforms/android:x86_64,//bazel/platforms/android:armeabi-v7a,//bazel/platforms/android:arm64-v8a \ |
||||
//examples/android/binder/java/io/grpc/binder/cpp/exampleclient:app \ |
||||
//examples/android/binder/java/io/grpc/binder/cpp/exampleserver:app |
||||
|
||||
# Make sure the Java code that will be invoked by binder transport |
||||
# implementation builds |
||||
python3 tools/run_tests/python_utils/bazel_report_helper.py --report_path bazel_binder_connection_helper |
||||
bazel_binder_connection_helper/bazel_wrapper \ |
||||
--bazelrc=tools/remote_build/include/test_locally_with_resultstore_results.bazelrc \ |
||||
build \ |
||||
--define=use_strict_warning=true \ |
||||
@binder_transport_android_helper//io/grpc/binder/cpp:connection_helper |
Loading…
Reference in new issue