grpc/grpc-java

Set User-Agent on CronetEngine now that crbug.com/588204 is fixed

groakley opened this issue · 1 comments

Summary

This is a request to resolve this TODO, and to use a better default User-Agent if none is provided to the CronetChannelBuilder.

Problem

If CronetChannelBuilder is used without calling userAgent(), gRPC/Cronet will set a User-Agent with the following form, which lacks any version info about the calling app package, device build, language, or Cronet version, like:

grpc-java-cronet/1.68.0-SNAPSHOT,gzip(gfe),gzip(gfe)

Because of this, many teams use the CronetEngine.Builder to set an explicit User-Agent, like:

 CronetChannelBuilder.forAddress("host", 123, cronetEngine)
     .userAgent(new CronetEngine.Builder(context).getDefaultUserAgent())
    // ...
    .build();

This results in something more useful like:

com.foo.app.package.helloworld/1 (Linux; U; Android 14; en_US; mokey; Build/UP1A.230518.002; Cronet/131.0.6724.0) grpc-java-cronet/1.68.0-SNAPSHOT,gzip(gfe),gzip(gfe)

But setting the User-Agent manually like this has a few issues:

  1. Calling new CronetEngine.Builder(context) is potentially expensive, even more expensive that simply building the CronetEngine instance (if the CronetEngine was instantiated using manual selection). This cost can be rectified by also using manual selection for the CronetEngine.Builder, but this is somewhat verbose simply to get the User-Agent.
  2. It's error prone. The CronetEngine.Builder and CronetEngine do not necessarily match.
  3. It's easily-forgotten.

Proposals

1. Without Cronet changes

If CronetChannelBuilder#userAgent() is not called, use the default CronetEngine User-Agent rather than gRPC's. That results in:

com.google.apps.tiktok.helloworld.grpc/1 (Linux; U; Android 14; en_US; mokey; Build/UP1A.230518.002; Cronet/131.0.6724.0),gzip(gfe),gzip(gfe)

We feel that this provides more useful user-agent info than the gRPC version, although I suspect that dropping the gRPC version is also undesirable.

2. With Cronet changes

Unfortunately the previous proposal lacks the grpc version portion. If possible, it would be better to concatenate gRPC's and Cronet's user agents to arrive at the desired User-Agent string containing both Cronet's and gRPC's user-agent shown above. However, I don't believe it is possible with the current Cronet API, replaces rather than prepending.

We can go with the proposal 1 to use the default CronetEngine user agent. May be we can make CronetClientStream append the gRPC version as well.