## File: README.md

gRPC-Java - An RPC library and framework
========================================



| **Homepage:** | [grpc.io](https://grpc.io/) |
| --- | --- |
| **Mailing List:** | [grpc-io@googlegroups.com](https://groups.google.com/forum/#!forum/grpc-io) |



[](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://github.com/grpc/grpc-java/actions/workflows/testing.yml?branch=master)
[](https://coveralls.io/github/grpc/grpc-java?branch=master)
[](https://codecov.io/gh/grpc/grpc-java)

Supported Platforms
-------------------

gRPC-Java supports Java 8 and later. Android minSdkVersion 24 (Nougat) and
later are supported with [Java 8 language desugaring][android-java-8].

TLS usage on Android typically requires Play Services Dynamic Security Provider.
Please see the [Security Readme](SECURITY.md).

Older Java versions are not directly supported, but a branch remains available
for fixes and releases. See [gRFC P5 JDK Version Support
Policy][P5-jdk-version-support].

Java version | gRPC Branch
------------ | -----------
7            | 1.41.x

[android-java-8]: https://developer.android.com/studio/write/java8-support#supported_features
[P5-jdk-version-support]: https://github.com/grpc/proposal/blob/master/P5-jdk-version-support.md#proposal

Getting Started
---------------

For a guided tour, take a look at the [quick start
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
basics](https://grpc.io/docs/languages/java/basics).

The [examples](https://github.com/grpc/grpc-java/tree/v1.83.1/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.83.1/examples/android)
are standalone projects that showcase the usage of gRPC.

Download
--------

Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
```xml
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-netty-shaded</artifactId>
  <version>1.83.1</version>
  <scope>runtime</scope>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-protobuf</artifactId>
  <version>1.83.1</version>
</dependency>
<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-stub</artifactId>
  <version>1.83.1</version>
</dependency>
```

Or for Gradle with non-Android, add to your dependencies:
```gradle
runtimeOnly 'io.grpc:grpc-netty-shaded:1.83.1'
implementation 'io.grpc:grpc-protobuf:1.83.1'
implementation 'io.grpc:grpc-stub:1.83.1'
```

For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
`grpc-protobuf-lite` instead of `grpc-protobuf`:
```gradle
implementation 'io.grpc:grpc-okhttp:1.83.1'
implementation 'io.grpc:grpc-protobuf-lite:1.83.1'
implementation 'io.grpc:grpc-stub:1.83.1'
```

For [Bazel](https://bazel.build), you can either
[use Maven](https://github.com/bazelbuild/rules_jvm_external)
(with the GAVs from above), or use `@io_grpc_grpc_java//api` et al (see below).

[the JARs]:
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.83.1

Development snapshots are available in [Sonatypes's snapshot
repository](https://central.sonatype.com/repository/maven-snapshots/).

Generated Code
--------------

For protobuf-based codegen, you can put your proto files in the `src/main/proto`
and `src/test/proto` directories along with an appropriate plugin.

For protobuf-based codegen integrated with the Maven build system, you can use
[protobuf-maven-plugin][] (Eclipse and NetBeans users should also look at
`os-maven-plugin`'s
[IDE documentation](https://github.com/trustin/os-maven-plugin#issues-with-eclipse-m2e-or-other-ides)):
```xml

  <extensions>
    <extension>
      <groupId>kr.motd.maven</groupId>
      <artifactId>os-maven-plugin</artifactId>
      <version>1.7.1</version>
    </extension>
  </extensions>
  
    
      <groupId>org.xolstice.maven.plugins</groupId>
      <artifactId>protobuf-maven-plugin</artifactId>
      <version>0.6.1</version>
      <configuration>
        com.google.protobuf:protoc:3.25.8:exe:${os.detected.classifier}
        grpc-java
        io.grpc:protoc-gen-grpc-java:1.83.1:exe:${os.detected.classifier}
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>compile-custom</goal>
          </goals>
        </execution>
      </executions>
    
  

```

[protobuf-maven-plugin]: https://www.xolstice.org/protobuf-maven-plugin/

For non-Android protobuf-based codegen integrated with the Gradle build system,
you can use [protobuf-gradle-plugin][]:
```gradle
plugins {
    id 'com.google.protobuf' version '0.9.5'
}

protobuf {
  protoc {
    artifact = "com.google.protobuf:protoc:3.25.8"
  }
  plugins {
    grpc {
      artifact = 'io.grpc:protoc-gen-grpc-java:1.83.1'
    }
  }
  generateProtoTasks {
    all()*.plugins {
      grpc {}
    }
  }
}
```

[protobuf-gradle-plugin]: https://github.com/google/protobuf-gradle-plugin

The prebuilt protoc-gen-grpc-java binary uses glibc on Linux. If you are
compiling on Alpine Linux, you may want to use the [Alpine grpc-java package][]
which uses musl instead.

[Alpine grpc-java package]: https://pkgs.alpinelinux.org/package/edge/community/x86_64/grpc-java

For Android protobuf-based codegen integrated with the Gradle build system, also
use protobuf-gradle-plugin but specify the 'lite' options:

```gradle
plugins {
    id 'com.google.protobuf' version '0.9.5'
}

protobuf {
  protoc {
    artifact = "com.google.protobuf:protoc:3.25.8"
  }
  plugins {
    grpc {
      artifact = 'io.grpc:protoc-gen-grpc-java:1.83.1'
    }
  }
  generateProtoTasks {
    all().each { task ->
      task.builtins {
        java { option 'lite' }
      }
      task.plugins {
        grpc { option 'lite' }
      }
    }
  }
}

```

For [Bazel](https://bazel.build), use the [`proto_library`](https://github.com/bazelbuild/rules_proto)
and the [`java_proto_library`](https://bazel.build/reference/be/java#java_proto_library) (no `load()` required) 
and `load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")` (from this project), as in
[this example `BUILD.bazel`](https://github.com/grpc/grpc-java/blob/master/examples/BUILD.bazel).

API Stability
-------------

APIs annotated with `@Internal` are for internal use by the gRPC library and
should not be used by gRPC users. APIs annotated with `@ExperimentalApi` are
subject to change in future releases, and library code that other projects
may depend on should not use these APIs.

We recommend using the
[grpc-java-api-checker](https://github.com/grpc/grpc-java-api-checker)
(an [Error Prone](https://github.com/google/error-prone) plugin)
to check for usages of `@ExperimentalApi` and `@Internal` in any library code
that depends on gRPC. It may also be used to check for `@Internal` usage or
unintended `@ExperimentalApi` consumption in non-library code.

How to Build
------------

If you are making changes to gRPC-Java, see the [compiling
instructions](COMPILING.md).

High-level Components
---------------------

At a high level there are three distinct layers to the library: *Stub*,
*Channel*, and *Transport*.

### Stub

The Stub layer is what is exposed to most developers and provides type-safe
bindings to whatever datamodel/IDL/interface you are adapting. gRPC comes with
a [plugin](https://github.com/google/grpc-java/blob/master/compiler) to the
protocol-buffers compiler that generates Stub interfaces out of `.proto` files,
but bindings to other datamodel/IDL are easy and encouraged.

### Channel

The Channel layer is an abstraction over Transport handling that is suitable for
interception/decoration and exposes more behavior to the application than the
Stub layer. It is intended to be easy for application frameworks to use this
layer to address cross-cutting concerns such as logging, monitoring, auth, etc.

### Transport

The Transport layer does the heavy lifting of putting and taking bytes off the
wire. The interfaces to it are abstract just enough to allow plugging in of
different implementations. Note the transport layer API is considered internal
to gRPC and has weaker API guarantees than the core API under package `io.grpc`.

gRPC comes with multiple Transport implementations:

1. The Netty-based HTTP/2 transport is the main transport implementation based
   on [Netty](https://netty.io). It is not officially supported on Android.
   There is a "grpc-netty-shaded" version of this transport. It is generally
   preferred over using the Netty-based transport directly as it requires less
   dependency management and is easier to upgrade within many applications.
2. The OkHttp-based HTTP/2 transport is a lightweight transport based on
   [Okio](https://square.github.io/okio/) and forked low-level parts of
   [OkHttp](https://square.github.io/okhttp/). It is mainly for use on Android.
3. The in-process transport is for when a server is in the same process as the
   client. It is used frequently for testing, while also being safe for
   production use.
4. The Binder transport is for Android cross-process communication on a single
   device.

---

## File: android-interop-testing/README.md

gRPC Android test App
=======================

Implements gRPC integration tests in an Android App.

In order to build this app, you need a local.properties file under this directory which specifies
the location of your android sdk:
```
sdk.dir=/somepath/somepath/sdk
```

Connect your Android device or start the emulator:
```
$ ./start-emulator.sh <AVD name> & ./wait-for-emulator.sh
```

Start test server
-----------------

Start the test server by:
```
$ ../run-test-server.sh
```


Manually test
-------------

Install the App by:
```
$ ../gradlew installDebug
```
Then manually test it with the UI.


Instrumentation tests
----------------

Instrumentation tests must be run on a connected device or emulator. Run with the
following gradle command:

```
$ ../gradlew connectedAndroidTest \
    -Pandroid.testInstrumentationRunnerArguments.server_host=10.0.2.2 \
    -Pandroid.testInstrumentationRunnerArguments.server_port=8080 \
    -Pandroid.testInstrumentationRunnerArguments.use_tls=true \
    -Pandroid.testInstrumentationRunnerArguments.server_host_override=foo.test.google.fr \
    -Pandroid.testInstrumentationRunnerArguments.use_test_ca=true \
    -Pandroid.testInstrumentationRunnerArguments.test_case=all
```

---

## File: benchmarks/README.md

grpc Benchmarks
==============================================

## QPS Benchmark

The "Queries Per Second Benchmark" allows you to get a quick overview of the throughput and latency characteristics of grpc.

To build the benchmark type

```
$ ./gradlew :grpc-benchmarks:installDist
```

from the grpc-java directory.

You can now find the client and the server executables in `benchmarks/build/install/grpc-benchmarks/bin`.

The `C++` counterpart can be found at https://github.com/grpc/grpc/tree/master/test/cpp/qps

The [netty benchmark](src/jmh/java/io/grpc/benchmarks/netty) directory contains
the standard benchmarks used to assess the performance of GRPC. Since these
benchmarks run on localhost over loopback the performance of the underlying network is considerably
different to real networks and their behavior. To address this issue we recommend the use of
a network emulator to make loopback behave more like a real network. To this end the benchmark
code looks for a loopback interface with 'benchmark' in its name and attempts to use the address
bound to that interface when creating the client and server. If it cannot find such an interface it
will print a warning and continue with the default localhost address.

To attempt to standardize benchmark behavior across machines we attempt to emulate a 10gbit
ethernet interface with a packet delay of 0.1ms.

### Linux

On Linux we can use [netem](https://www.linuxfoundation.org/collaborate/workgroups/networking/netem)  to shape the traffic appropriately.

```sh
# Remove all traffic shaping from loopback
sudo tc qdisc del dev lo root
# Add a priority traffic class to the root of loopback
sudo tc qdisc add dev lo root handle 1: prio
# Add a qdisc under the new class with the appropriate shaping
sudo tc qdisc add dev lo parent 1:1 handle 2: netem delay 0.1ms rate 10gbit
# Add a filter which selects the new qdisc class for traffic to 127.127.127.127
sudo tc filter add dev lo parent 1:0 protocol ip prio 1 u32 match ip dst 127.127.127.127 flowid 2:1
# Create an interface alias call 'lo:benchmark' that maps 127.127.127.127 to loopback
sudo ip addr add dev lo 127.127.127.127/32 label lo:benchmark
```

to remove this configuration

```sh
sudo tc qdisc del dev lo root
sudo ip addr del dev lo 127.127.127.127/32 label lo:benchmark
```

### Other Platforms

Contributions are welcome!

## Visualizing the Latency Distribution

The QPS client comes with the option `--save_histogram=FILE`, if set it serializes the histogram to `FILE` which can then be used with a plotter to visualize the latency distribution. The histogram is stored in the file format of [HdrHistogram](https://hdrhistogram.org/). That way it can be plotted very easily using a browser based tool like https://hdrhistogram.github.io/HdrHistogram/plotFiles.html. Simply upload the generated file and it will generate a beautiful graph for you. It also allows you to plot two or more histograms on the same surface in order two easily compare latency distributions.

## JVM Options

When running a benchmark it's often useful to adjust some JVM options to improve performance and to gain some insights into what's happening. Passing JVM options to the QPS server and client is as easy as setting the `JAVA_OPTS` environment variables. Below are some options that I find very useful:
 - `-Xms` gives a lower bound on the heap to allocate and `-Xmx` gives an upper bound. If your program uses more than what's specified in `-Xmx` the JVM will exit with an `OutOfMemoryError`. When setting those always set `Xms` and `Xmx` to the same value. The reason for this is that the young and old generation are sized according to the total available heap space. So if the total heap gets resized, they will also have to be resized and this will then trigger a full GC.
 - `-verbose:gc` prints some basic information about garbage collection. It will log to stdout whenever a GC happend and will tell you about the kind of GC, pause time and memory compaction.
 - `-XX:+PrintGCDetails` prints out very detailed GC and heap usage information before the program terminates.
 - `-XX:-HeapDumpOnOutOfMemoryError` and `-XX:HeapDumpPath=path` when you are pushing the JVM hard it sometimes happens that it will crash due to the lack of available heap space. This option will allow you to dive into the details of why it happened. The heap dump can be viewed with e.g. the [Eclipse Memory Analyzer](https://eclipse.org/mat/).
 - `-XX:+PrintCompilation` will give you a detailed overview of what gets compiled, when it gets compiled, by which HotSpot compiler it gets compiled and such. It's a lot of output. I usually just redirect it to file and look at it with `less` and `grep`.
 - `-XX:+PrintInlining` will give you a detailed overview of what gets inlined and why some methods didn't get inlined. The output is very verbose and like `-XX:+PrintCompilation` and useful to look at after some major changes or when a drop in performance occurs.
 - It sometimes happens that a benchmark just doesn't make any progress, that is no bytes are transferred over the network, there is hardly any CPU utilization and low memory usage but the benchmark is still running. In that case it's useful to get a thread dump and see what's going on. HotSpot ships with a tool called `jps` and `jstack`. `jps` tells you the process id of all running JVMs on the machine, which you can then pass to `jstack` and it will print a thread dump of this JVM.
 - Taking a heap dump of a running JVM is similarly straightforward. First get the process id with `jps` and then use `jmap` to take the heap dump. You will almost always want to run it with `-dump:live` in order to only dump live objects. If possible, try to size the heap of your JVM (`-Xmx`) as small as possible in order to also keep the heap dump small. Large heap dumps are very painful and slow to analyze.

## Profiling

Newer JVMs come with a built-in profiler called `Java Flight Recorder`. It's an excellent profiler and it can be used to start a recording directly on the command line,  from within `Java Mission Control` or
with jcmd.

A good introduction on how it works and how to use it are http://hirt.se/blog/?p=364 and http://hirt.se/blog/?p=370.

---

## File: compiler/README.md

gRPC Java Codegen Plugin for Protobuf Compiler
==============================================

This generates the Java interfaces out of the service definition from a
`.proto` file. It works with the Protobuf Compiler (``protoc``).

Normally you don't need to compile the codegen by yourself, since pre-compiled
binaries for common platforms are available on Maven Central:

1. Navigate to https://mvnrepository.com/artifact/io.grpc/protoc-gen-grpc-java
2. Click into a version
3. Click "Files"

However, if the pre-compiled binaries are not compatible with your system,
you may want to build your own codegen.

## Compiling and testing the codegen

Set up your system as described in [COMPILING.md](../COMPILING.md).

Then change to the `compiler` directory:
```
$ cd $GRPC_JAVA_ROOT/compiler
```

To compile the plugin:
```
$ ../gradlew java_pluginExecutable
```

To test the plugin with the compiler:
```
$ ../gradlew test
```
You will see a `PASS` if the test succeeds.

To compile a proto file and generate Java interfaces out of the service definitions:
```
$ protoc --plugin=protoc-gen-grpc-java=build/exe/java_plugin/protoc-gen-grpc-java \
  --grpc-java_out="$OUTPUT_FILE" --proto_path="$DIR_OF_PROTO_FILE" "$PROTO_FILE"
```
To generate Java interfaces with protobuf lite:
```
$ protoc --plugin=protoc-gen-grpc-java=build/exe/java_plugin/protoc-gen-grpc-java \
  --grpc-java_out=lite:"$OUTPUT_FILE" --proto_path="$DIR_OF_PROTO_FILE" "$PROTO_FILE"
```

## Installing the codegen to Maven local repository
This will compile a codegen and put it under your ``~/.m2/repository``. This
will make it available to any build tool that pulls codegens from Maven
repositories.
```
$ ../gradlew publishToMavenLocal
```

## Creating a release of gRPC Java
Please follow the instructions in ``RELEASING.md`` under the root directory for
details on how to create a new release.

---

## File: cronet/README.md

gRPC Cronet Transport
========================

**EXPERIMENTAL:**  *gRPC's Cronet transport is an experimental API. Its stability
depends on upstream Cronet's implementation, which involves some experimental features.*

This code enables using the [Chromium networking stack
(Cronet)](https://chromium.googlesource.com/chromium/src/+/master/components/cronet)
as the transport layer for gRPC on Android. This lets your Android app make
RPCs using the same networking stack as used in the Chrome browser.

Some advantages of using Cronet with gRPC:

* Bundles an OpenSSL implementation, enabling TLS connections even on older
  versions of Android without additional configuration
* Robust to Android network connectivity changes
* Support for [QUIC](https://www.chromium.org/quic)

Since gRPC's 1.24 release, the `grpc-cronet` package provides access to the 
`CronetChannelBuilder` class. Cronet jars are available on Google's Maven repository. 
See the example app at https://github.com/GoogleChrome/cronet-sample/blob/master/README.md.

## Example usage:

In your app module's `build.gradle` file, include a dependency on both
`io.grpc:grpc-cronet` and the Google Play Services Client Library for Cronet,
`com.google.android.gms:play-services-cronet`.

In cases where Cronet cannot be loaded from Google Play services, there is a less performant 
implementation of Cronet's API that can be used. Depend on `org.chromium.net:cronet-fallback` 
to use this fall-back implementation.


You will also need permission to access the device's network state in your 
`AndroidManifest.xml`:

```

```

Once the above steps are completed, you can create a gRPC Cronet channel as
follows:

```
import io.grpc.cronet.CronetChannelBuilder;
import org.chromium.net.ExperimentalCronetEngine;

...

ExperimentalCronetEngine engine =
    new ExperimentalCronetEngine.Builder(context /* Android Context */).build();
ManagedChannel channel = CronetChannelBuilder.forAddress("localhost", 8080, engine).build();
```

---

## File: documentation/android-binderchannel-status-codes.md

# Android gRPC/BinderChannel Status Codes

## Background

[BinderChannel](https://github.com/grpc/proposal/blob/master/L73-java-binderchannel.md) is a gRPC transport that lets Android apps communicate across processes using familiar gRPC concepts and APIs. A BinderChannel-backed gRPC request can fail for many Android-specific reasons, both at `ServiceConnection` establishment and at `transact()` time. These transport-specific failures must be reported to clients using [gRPC’s standard canonical status code abstraction](https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc). This document enumerates the BinderChannel errors one can expect to encounter, specifies a canonical status code mapping for each possibility and discusses how clients should handle them.


## Status Code Mapping

Consider the table that follows as an BinderChannel-specific addendum to the “[Codes that may be returned by the gRPC libraries](https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc)” document. Mappings in that table that share a status code with one of the binder-specific mappings are repeated here for comparison.



| **#** | **Error Case** | **Android API Manifestation** | **Status Code** | **Expected Client Handling** |
| --- | --- | --- | --- | --- |
| 0 | [Server app not visible](https://developer.android.com/training/package-visibility). | bindService() returns false | UNIMPLEMENTED“The operation is not implemented or is not supported / enabled in this service.” | Give up - This is an error in the client manifest. |
| 1 | [Safer Intents](https://developer.android.com/about/versions/15/behavior-changes-15#safer-intents) violation. | Direct the user to install/reinstall the server app. |  |  |
| 2 | Server app not installed |  |  |  |
| 3 | Old version of the server app doesn’t declare the target android.app.Service in its manifest. |  |  |  |
| 4 | Target android.app.Service is disabled |  |  |  |
| 5 | The whole server app is disabled |  |  |  |
| 6 | Server app predates [the Android M permissions model](https://developer.android.com/guide/topics/permissions/overview) and the user must review and approve some newly requested permissions before it can run. |  |  |  |
| 7 | Target android.app.Service doesn’t recognize grpc binding Intent (old version of server app?) | onNullBinding() ServiceConnection callback |  |  |
| 8 | Method not found on the io.grpc.Server (old version of server app?) | N/A |  |  |
| 9 | Request cardinality violation (old version of server app expects unary rather than streaming, say) |  |  |  |
| 10 | Old version of the server app exposes target android.app.Service but doesn’t android:export it. | bindService() throws SecurityException | PERMISSION_DENIED
“The caller does not have permission to execute the specified operation …” | Direct the user to update the server app in the hopes that a newer version fixes this error in its manifest. |
| 11 | Target android.app.Service requires an &lt;android:permission&gt; that client doesn’t hold. | Prompt the user to grant the needed Android permission |  |  |
| 12 | Violations of the security policy for miscellaneous Android features like android:isolatedProcess, android:externalService, android:singleUser, instant apps, BIND_TREAT_LIKE_ACTIVITY, etc, | Give up - This is a programming or packaging error that only the app developer can fix. |  |  |
| 13 | Calling Android UID not allowed by ServerSecurityPolicy | N/A |  |  |
| 14 | Server Android UID not allowed by client’s SecurityPolicy |  |  |  |
| 15 | Server process crashed or killed with request in flight. | onDisconnected() ServiceConnection callback | UNAVAILABLE

“The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff ...” | Retry with exponential backoff and deadline (see [ManagedChannelBuilder#enableRetry()](https://grpc.github.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#enableRetry--) |
| onBinderDied() IBinder.DeathRecipient callback |  |  |  |  |
| IBinder.transact() throws DeadObjectException |  |  |  |  |
| 16 | Server app is currently being upgraded to a new version | onBindingDied() ServiceConnection callback |  |  |
| 17 | The whole server app or the target android.app.Service was disabled |  |  |  |
| 18 | Binder transaction buffer overflow | IBinder.transact() throws TransactionTooLargeException |  |  |
| 19 | Source Context for bindService() is destroyed with a request in flight | onDestroy() | CANCELLED

“The operation was cancelled, typically by the caller.” | Give up for now.

(Re. 19: The caller can try again later when the user opens the source Activity or restarts the source Service) |
| 20 | Client application cancelled the request | N/A |  |  |
| 21 | Bug in Android itself or the way the io.grpc.binder transport uses it. | IBinder.transact() returns false | INTERNAL

“This means that some invariants expected by the underlying system have been broken. … Reserved for serious errors.” | Give up - This is a programming error that only the app or grpc developers can fix |
| bindService() throws IllegalArgumentException |  |  |  |  |
| 22 | Flow-control protocol violation | N/A |  |  |
| 23 | Can’t parse request/response proto |  |  |  |




### Ambiguity

We say a status code is ambiguous if it maps to two error cases that reasonable clients want to handle differently. For instance, a client may have good reasons to handle error cases 10 and 11 above differently. But they can’t do so based on status code alone because those error cases map to the same one. 

In contrast, for example, even though error case 19 and 20 both map to the status code (`CANCELLED`), they are not ambiguous because we see no reason that clients would want to distinguish them. In both cases, clients will simply give up on the request.


#### Ambiguity of PERMISSION_DENIED and Mitigations

The mapping above has only one apparently ambiguous status code: `PERMISSION_DENIED`. However, this isn’t so bad because of the following:

The use of `<android:permission>`s for inter-app IPC access control (error case 11) is uncommon. Instead, we recommend that server apps only allow IPC from a limited set of client apps known in advance and identified by signature.

However, there may be gRPC server apps that want to use custom &lt;android:permission&gt;’s to let the end user decide which arbitrary other apps can make use of its gRPC services. In that case, clients should preempt error case 11 simply by [checking whether they hold the required permissions](https://developer.android.com/training/permissions/requesting) before sending a request.

Server apps can avoid error case 10 by never reusing an android.app.Service as a gRPC host if it has ever been android:exported=false in some previous app version. Instead they should simply create a new android.app.Service for this purpose.

Only error cases 12 - 14 remain, making `PERMISSION_DENIED` unambiguous for the purpose of error handling. Reasonable client apps can handle it in a generic way by displaying an error message and/or proceeding with degraded functionality.


#### Non-Ambiguity of UNIMPLEMENTED

The `UNIMPLEMENTED` status code corresponds to quite a few different problems with the server app: It’s either not installed, too old, misconfigured, or disabled in whole or in part. Despite the diversity of underlying error cases, we believe most client apps will and should handle `UNIMPLEMENTED` in the same way: by sending the user to the app store to (re)install the server app. Reinstalling might be overkill for the disabled cases but most end users don't know what it means to enable/disable an app and there’s neither enough space in a UI dialog nor enough reader attention to explain it. Reinstalling is something users likely already understand and likely to cure problems 0-9 (once a fixed version of the server is available).


## Detailed Discussion of Binder Failure Modes

### IBinder.transact() returns false

According to the [docs](https://developer.android.com/reference/android/os/IBinder#transact(int,%20android.os.Parcel,%20android.os.Parcel,%20int)), false “generally means the transaction code was not understood.” This is true for synchronous transactions but all gRPC/BinderChannel transactions are `FLAG_ONEWAY` meaning the calling thread doesn’t wait around for the server to return from `onTransact()`. Examination of the AOSP source code shows several additional undocumented reasons `transact()` could return false but all of these cases should be impossible and aren’t things that reasonable apps want to handle.

### IBinder.transact() Throws an Exception

According to the docs, `transact()` can throw `RemoteException` but the significance of this exception [isn’t documented](https://developer.android.com/reference/android/os/IBinder#transact(int,%20android.os.Parcel,%20android.os.Parcel,%20int)). By inspection of the AOSP source, we see there are several cases:

1. The remote process is no longer alive (`android.os.DeadObjectException`)
2. The IPC buffer is full (`android.os.TransactionTooLargeException`)
3. Certain internal errors from the underlying `ioctl()` system call.

Status code mappings: 


| **Exception** | **Status Code** | **Rationale** |
| --- | --- | --- |
| android.os.DeadObjectException | UNAVAILABLE | So the caller can retry against a new incarnation of the server process |
| android.os.TransactionTooLargeException | UNAVAILABLE | These are usually transient. A retry is likely to succeed later when demand for the IPC buffer subsides. |
| Some other RemoteException | INTERNAL | So the caller doesn’t bother retrying |
| Some other RuntimeException | INTERNAL |  |




### bindService() returns false

According to the [docs](https://developer.android.com/reference/android/content/Context#bindService(android.content.Intent,%20android.content.ServiceConnection,%20int)), this bindService() returns false when “the system couldn't find the service or if your client doesn't have permission to bind to it.” However, the part about permission is somewhat misleading.

According to a review of the AOSP source code, there are in fact several cases:

1. The target package is not installed
2. The target package is installed but does not declare the target Service in its manifest.
3. The target package requests dangerous permissions but targets sdk &lt;= M and therefore requires a permissions review, but the caller is not running in the foreground and so it would be inappropriate to launch the review UI.
4. The target package is not visible to the client due to [Android 11 package visibility rules](https://developer.android.com/training/package-visibility).
5. One of the new [Safer Intents](https://developer.android.com/about/versions/15/behavior-changes-15#safer-intents) rules is violated. Most commonly, the bind `Intent` specifies a `ComponentName` explicitly but doesn't match any of its &lt;intent-filter&gt;s. 

Status code mapping: **UNIMPLEMENTED**

(1) and (2) are interesting new possibilities unique to on-device RPC. (1) is straightforward and the most likely cause of (2) is that the user has an old version of the server app installed that predates its gRPC integration. Many clients will want to handle these cases, likely by directing the user to the app store in order to install/upgrade the server.

Unfortunately `UNIMPLEMENTED` doesn’t capture (3) but none of the other canonical status codes do either and we expect this case to be extremely rare.

(4) and (5) are intentially indistinguishable from (1) by Android design so we can't handle them differently. However, as an error in its own manifest, (4) isn't something a reasonable client would handle at runtime anyway. (5) is an error in the server manifest and so, just like the other cases, the best practice for handling it is to send the user to the app store in the hope that the server can be updated with a fix.

### bindService() throws SecurityException

According to the [docs](https://developer.android.com/reference/android/content/Context#bindService(android.content.Intent,%20android.content.ServiceConnection,%20int)), SecurityException is thrown “if the calling app does not have permission to bind to the given service”. There are quite a few specific cases:

1. The target Service sets `android:exported = “false”` in its manifest but the caller is in a different app.
2. The target Service declares a required permission in its manifest but the calling package doesn’t have it. 
3. The target Service is marked as `android:singleton` in the manifest but doesn’t hold the `INTERACT_ACROSS_USERS` permission. 
4. The caller is an `android:isolatedProcess`.
5. The caller requested certain security-related flags on the binding without the necessary permission (gRPC/BinderChannel doesn’t do this)
6. … according to the source code, a long tail of unlikely security-related internal errors.

Status code mapping: **PERMISSION_DENIED**.

### bindService() throws IllegalArgumentException

There are a couple cases:

1. The binding Intent is not explicit.
2. The binding Intent contains file descriptors.

Status Code mapping: **INTERNAL**. These cases should be impossible. 


### onBindingDied() ServiceConnection callback

According to the [docs](https://developer.android.com/reference/android/content/ServiceConnection#onBindingDied(android.content.ComponentName)): “... This means the interface will never receive another connection. The application will need to unbind and rebind the connection to activate it again. This may happen, for example, if the application hosting the service it is bound to has been updated.”

Status code mapping: **UNAVAILABLE**

`UNAVAILABLE` is the best mapping since a retry is likely to succeed in the near future once the server application finishes updating. 


### onNullBinding() ServiceConnection callback

According to the [docs](https://developer.android.com/reference/android/content/ServiceConnection#onNullBinding(android.content.ComponentName)): “Called when the service being bound has returned null from its `onBind()` method. This indicates that the attempting service binding represented by this `ServiceConnection` will never become usable.”

Status code mapping: **UNIMPLEMENTED**

`UNIMPLEMENTED` is used here because a retry is likely to fail for the same reason. The most likely root cause for a null binding is an older version of the server app where the `android.app.Service` exists but either doesn’t implement `onBind()` or doesn’t recognize the `grpc.io.action.BIND` Intent action.


### onServiceDisconnected() ServiceConnection callback

According to the [docs](https://developer.android.com/reference/android/content/ServiceConnection#onServiceDisconnected(android.content.ComponentName)): “Called when a connection to the Service has been lost. This typically happens when the process hosting the service has crashed or been killed ...”

Status code mapping: **UNAVAILABLE**

`UNAVAILABLE` is used here since a retry is likely to succeed against a newly restarted instance of the server.


### Response Parcel Contains an Exception

Android’s Parcel class exposes a mechanism for marshalling certain types of `RuntimeException`s between traditional Binder IPC peers. However we won’t consider this case because gRPC/BinderChannel doesn’t use this mechanism. In fact, all BinderChannel transactions are `FLAG_ONE_WAY` so there is no response Parcel.


### Source Context for bindService() is Destroyed

The calling Activity or Service Context might be destroyed with a gRPC request in flight. Apps should cease operations when the Context hosting it goes away and this includes cancelling any outstanding RPCs.  

Status code mapping: **CANCELLED**

---

## File: documentation/android-channel-builder.md

# AndroidChannelBuilder

 The `grpc-android` package provides access to the
`AndroidChannelBuilder` class. Given an Android Context, this builder
registers a network event listener upon channel construction.  The listener
automatically responds to changes in the device's network state, avoiding
delays and interrupted RPCs that may otherwise occur.

By default, gRPC uses exponential backoff to recover from connection failures.
Depending on the scheduled backoff delay when the device regains connectivity,
this could result in a  one minute or longer delay before gRPC re-establishes
the connection. This delay is removed when `AndroidChannelBuilder` is provided
with the app's Android Context.  Notifications from the network listener
cause the channel to immediately reconnect upon network recovery.

On Android API levels 24+, `AndroidChannelBuilder`'s network listener mechanism
allows graceful switching from cellular to wifi connections. When an Android
device on a cellular network connects to a wifi network, there is a brief
(typically 30 second) interval when both cellular and wifi networks remain
available, then any connections on the cellular network are terminated.  By
listening for changes in the device's default network, `AndroidChannelBuilder`
sends new RPCs via wifi rather than using an already-established cellular
connection. Without listening for pending network changes, new RPCs sent on an
already established cellular connection would fail when the device terminates
cellular connections.

***Note:*** *Currently, `AndroidChannelBuilder` is only compatible with gRPC
OkHttp. We plan to offer additional Android-specific features compatible with
both the OkHttp and Cronet transports in the future, but the network listener
mechanism is only necessary with OkHttp; the Cronet library internally handles
connection management on Android devices.*

## Example usage:

In your `build.gradle` file, include a dependency on both `io.grpc:grpc-android` and
`io.grpc:grpc-okhttp`.

You also need permission to access the device's network state in your
`AndroidManifest.xml`:

```

```

When constructing your channel, use `AndroidChannelBuilder` and provide it with
your app's Context:

```
import io.grpc.android.AndroidChannelBuilder;
...
ManagedChannel channel = AndroidChannelBuilder.forAddress("localhost", 8080)
    .context(getApplicationContext())
    .build();
```

You continue to use the constructed channel exactly as you would any other
channel. gRPC will now monitor and respond to the device's network state
automatically. When you shutdown the managed channel, the network listener
registered by `AndroidChannelBuilder` will be unregistered.

---

## File: documentation/server-reflection-tutorial.md

# gRPC Server Reflection Tutorial

gRPC Server Reflection provides information about publicly-accessible gRPC
services on a server, and assists clients at runtime with constructing RPC
requests and responses without precompiled service information. It is used by
the gRPC command line tool (gRPC CLI), which can be used to introspect server
protos and send/receive test RPCs. Reflection is only supported for
proto-based services.

## Enable Server Reflection

gRPC-Java Server Reflection is implemented by
`io.grpc.protobuf.services.ProtoReflectionServiceV1` in the `grpc-services`
package. To enable server reflection, you need to add the
`ProtoReflectionServiceV1` to your gRPC server.

For example, to enable server reflection in
`examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java`, we
need to make the following changes:

```diff
--- a/examples/build.gradle
+++ b/examples/build.gradle
@@ -27,6 +27,7 @@
 dependencies {
   compile "io.grpc:grpc-netty-shaded:${grpcVersion}"
   compile "io.grpc:grpc-protobuf:${grpcVersion}"
+  compile "io.grpc:grpc-services:${grpcVersion}"
   compile "io.grpc:grpc-stub:${grpcVersion}"
 
   testCompile "junit:junit:4.13.2"
--- a/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java
+++ b/examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java
@@ -33,6 +33,7 @@ package io.grpc.examples.helloworld;
 
 import io.grpc.Server;
 import io.grpc.ServerBuilder;
+import io.grpc.protobuf.services.ProtoReflectionServiceV1;
 import io.grpc.stub.StreamObserver;
 import java.io.IOException;
 import java.util.logging.Logger;
@@ -50,6 +51,7 @@ public class HelloWorldServer {
     int port = 50051;
     server = ServerBuilder.forPort(port)
         .addService(new GreeterImpl())
+        .addService(ProtoReflectionServiceV1.newInstance())
         .build()
         .start();
     logger.info("Server started, listening on " + port);
```

In the following examples, we assume you have made these changes to
enable reflection in `HelloWorldServer.java`.

## gRPC CLI

After enabling server reflection in a server application, you can use gRPC
CLI to get information about its available services. gRPC CLI is written
in C++. Instructions on how to build gRPC CLI can be found at
[command_line_tool.md](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md).

## Use gRPC CLI to check services

First, build and start the `hello-world-server`:

```sh
$ cd examples/
$ ./gradlew installDist
$ build/install/examples/bin/hello-world-server
```

Open a new terminal and make sure you are in the directory where the `grpc_cli`
binary is located:

```sh
$ cd <grpc-cpp-directory>/bins/opt
```

### List services

`grpc_cli ls` command lists services and methods exposed at a given port:

- List all the services exposed at a given port

  ```sh
  $ ./grpc_cli ls localhost:50051
  ```

  output:
  ```sh
  helloworld.Greeter
  grpc.reflection.v1alpha.ServerReflection
  ```

- List one service with details

  `grpc_cli ls` command inspects a service given its full name (in the format of
  \.\<service\>). It can print information with a long listing format
  when `-l` flag is set. This flag can be used to get more details about a
  service.

  ```sh
  $ ./grpc_cli ls localhost:50051 helloworld.Greeter -l
  ```

  output:
  ```sh
  filename: helloworld.proto
  package: helloworld;
  service Greeter {
    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
  }

  ```

### List methods

- List one method with details

  `grpc_cli ls` command also inspects a method given its full name (in the
  format of \.\<service\>.\<method\>).

  ```sh
  $ ./grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l
  ```

  output:
  ```sh
    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
  ```

### Inspect message types

We can use`grpc_cli type` command to inspect request/response types given the
full name of the type (in the format of \.\<type\>).

- Get information about the request type

  ```sh
  $ ./grpc_cli type localhost:50051 helloworld.HelloRequest
  ```

  output:
  ```sh
  message HelloRequest {
    optional string name = 1[json_name = "name"];
  }
  ```

### Call a remote method

We can send RPCs to a server and get responses using `grpc_cli call` command.

- Call a unary method

  ```sh
  $ ./grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'"
  ```

  output:
  ```sh
  message: "Hello gRPC CLI"
  ```

---

## File: examples/android/strictmode/README.md

gRPC Android StrictMode Example
========================

- This example intends to show the compatibility of gRPC with Android StrictMode.
- Android SDK version 28 is required for [`StrictMode.VmPolicy.Builder.penaltyListener`](https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder.html#penaltyListener(java.util.concurrent.Executor,%20android.os.StrictMode.OnVmViolationListener)) used in the example.
- This example does the same thing as [HelloWorld example](../helloworld) except popping up a dialog for detected StrictMode policy violation (shown below).

---

## File: examples/android/README.md

gRPC Hello World Example (Android Java)
========================

PREREQUISITES
-------------
- [Java gRPC](https://github.com/grpc/grpc-java)

- [Android Tutorial](https://developer.android.com/training/basics/firstapp/index.html) if you're new to Android development

- [gRPC Java Android Quick Start Guide](https://grpc.io/docs/quickstart/android.html)

- We only have Android gRPC client in this example. Please follow examples in other languages to build and run a gRPC server.

INSTALL
-------

1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).**

2. Install the app
```sh
$ cd helloworld  # or "cd routeguide"
$ ../../gradlew installDebug
```

Please refer to the
[tutorial](https://grpc.io/docs/tutorials/basic/android.html) on
how to use gRPC in Android programs.