20
20
import static com .google .common .base .Preconditions .checkState ;
21
21
22
22
import android .content .Context ;
23
+ import android .os .UserHandle ;
23
24
import androidx .core .content .ContextCompat ;
24
25
import com .google .errorprone .annotations .DoNotCall ;
25
26
import io .grpc .ChannelCredentials ;
@@ -71,7 +72,37 @@ public final class BinderChannelBuilder
71
72
public static BinderChannelBuilder forAddress (
72
73
AndroidComponentAddress directAddress , Context sourceContext ) {
73
74
return new BinderChannelBuilder (
74
- checkNotNull (directAddress , "directAddress" ), null , sourceContext );
75
+ checkNotNull (directAddress , "directAddress" ),
76
+ null ,
77
+ sourceContext ,
78
+ BinderChannelCredentials .forDefault ());
79
+ }
80
+
81
+ /**
82
+ * Creates a channel builder that will bind to a remote Android service with provided
83
+ * BinderChannelCredentials.
84
+ *
85
+ * <p>The underlying Android binding will be torn down when the channel becomes idle. This happens
86
+ * after 30 minutes without use by default but can be configured via {@link
87
+ * ManagedChannelBuilder#idleTimeout(long, TimeUnit)} or triggered manually with {@link
88
+ * ManagedChannel#enterIdle()}.
89
+ *
90
+ * <p>You the caller are responsible for managing the lifecycle of any channels built by the
91
+ * resulting builder. They will not be shut down automatically.
92
+ *
93
+ * @param directAddress the {@link AndroidComponentAddress} referencing the service to bind to.
94
+ * @param sourceContext the context to bind from (e.g. The current Activity or Application).
95
+ * @param channelCredentials the arbitrary binder specific channel credentials to be used to
96
+ * establish a binder connection.
97
+ * @return a new builder
98
+ */
99
+ @ ExperimentalApi ("https://github.com/grpc/grpc-java/issues/10173" )
100
+ public static BinderChannelBuilder forAddress (
101
+ AndroidComponentAddress directAddress ,
102
+ Context sourceContext ,
103
+ BinderChannelCredentials channelCredentials ) {
104
+ return new BinderChannelBuilder (
105
+ checkNotNull (directAddress , "directAddress" ), null , sourceContext , channelCredentials );
75
106
}
76
107
77
108
/**
@@ -92,7 +123,37 @@ public static BinderChannelBuilder forAddress(
92
123
* @return a new builder
93
124
*/
94
125
public static BinderChannelBuilder forTarget (String target , Context sourceContext ) {
95
- return new BinderChannelBuilder (null , checkNotNull (target , "target" ), sourceContext );
126
+ return new BinderChannelBuilder (
127
+ null ,
128
+ checkNotNull (target , "target" ),
129
+ sourceContext ,
130
+ BinderChannelCredentials .forDefault ());
131
+ }
132
+
133
+ /**
134
+ * Creates a channel builder that will bind to a remote Android service, via a string target name
135
+ * which will be resolved.
136
+ *
137
+ * <p>The underlying Android binding will be torn down when the channel becomes idle. This happens
138
+ * after 30 minutes without use by default but can be configured via {@link
139
+ * ManagedChannelBuilder#idleTimeout(long, TimeUnit)} or triggered manually with {@link
140
+ * ManagedChannel#enterIdle()}.
141
+ *
142
+ * <p>You the caller are responsible for managing the lifecycle of any channels built by the
143
+ * resulting builder. They will not be shut down automatically.
144
+ *
145
+ * @param target A target uri which should resolve into an {@link AndroidComponentAddress}
146
+ * referencing the service to bind to.
147
+ * @param sourceContext the context to bind from (e.g. The current Activity or Application).
148
+ * @param channelCredentials the arbitrary binder specific channel credentials to be used to
149
+ * establish a binder connection.
150
+ * @return a new builder
151
+ */
152
+ @ ExperimentalApi ("https://github.com/grpc/grpc-java/issues/10173" )
153
+ public static BinderChannelBuilder forTarget (
154
+ String target , Context sourceContext , BinderChannelCredentials channelCredentials ) {
155
+ return new BinderChannelBuilder (
156
+ null , checkNotNull (target , "target" ), sourceContext , channelCredentials );
96
157
}
97
158
98
159
/**
@@ -121,12 +182,14 @@ public static BinderChannelBuilder forTarget(String target) {
121
182
private SecurityPolicy securityPolicy ;
122
183
private InboundParcelablePolicy inboundParcelablePolicy ;
123
184
private BindServiceFlags bindServiceFlags ;
185
+ @ Nullable private UserHandle targetUserHandle ;
124
186
private boolean strictLifecycleManagement ;
125
187
126
188
private BinderChannelBuilder (
127
189
@ Nullable AndroidComponentAddress directAddress ,
128
190
@ Nullable String target ,
129
- Context sourceContext ) {
191
+ Context sourceContext ,
192
+ BinderChannelCredentials channelCredentials ) {
130
193
mainThreadExecutor =
131
194
ContextCompat .getMainExecutor (checkNotNull (sourceContext , "sourceContext" ));
132
195
securityPolicy = SecurityPolicies .internalOnly ();
@@ -139,10 +202,12 @@ final class BinderChannelTransportFactoryBuilder
139
202
public ClientTransportFactory buildClientTransportFactory () {
140
203
return new TransportFactory (
141
204
sourceContext ,
205
+ channelCredentials ,
142
206
mainThreadExecutor ,
143
207
schedulerPool ,
144
208
managedChannelImplBuilder .getOffloadExecutorPool (),
145
209
securityPolicy ,
210
+ targetUserHandle ,
146
211
bindServiceFlags ,
147
212
inboundParcelablePolicy );
148
213
}
@@ -216,6 +281,23 @@ public BinderChannelBuilder securityPolicy(SecurityPolicy securityPolicy) {
216
281
return this ;
217
282
}
218
283
284
+ /**
285
+ * Provides the target {@UserHandle} of the remote Android service.
286
+ *
287
+ * <p>When targetUserHandle is set, Context.bindServiceAsUser will used and additional Android
288
+ * permissions will be required. If your usage does not require cross-user communications, please
289
+ * do not set this field. It is the caller's responsibility to make sure that it holds the
290
+ * corresponding permissions.
291
+ *
292
+ * @param targetUserHandle the target user to bind into.
293
+ * @return this
294
+ */
295
+ @ ExperimentalApi ("https://github.com/grpc/grpc-java/issues/10173" )
296
+ public BinderChannelBuilder bindAsUser (UserHandle targetUserHandle ) {
297
+ this .targetUserHandle = targetUserHandle ;
298
+ return this ;
299
+ }
300
+
219
301
/** Sets the policy for inbound parcelable objects. */
220
302
public BinderChannelBuilder inboundParcelablePolicy (
221
303
InboundParcelablePolicy inboundParcelablePolicy ) {
@@ -245,30 +327,36 @@ public BinderChannelBuilder idleTimeout(long value, TimeUnit unit) {
245
327
/** Creates new binder transports. */
246
328
private static final class TransportFactory implements ClientTransportFactory {
247
329
private final Context sourceContext ;
330
+ private final BinderChannelCredentials channelCredentials ;
248
331
private final Executor mainThreadExecutor ;
249
332
private final ObjectPool <ScheduledExecutorService > scheduledExecutorPool ;
250
333
private final ObjectPool <? extends Executor > offloadExecutorPool ;
251
334
private final SecurityPolicy securityPolicy ;
252
- private final InboundParcelablePolicy inboundParcelablePolicy ;
335
+ @ Nullable private final UserHandle targetUserHandle ;
253
336
private final BindServiceFlags bindServiceFlags ;
337
+ private final InboundParcelablePolicy inboundParcelablePolicy ;
254
338
255
339
private ScheduledExecutorService executorService ;
256
340
private Executor offloadExecutor ;
257
341
private boolean closed ;
258
342
259
343
TransportFactory (
260
344
Context sourceContext ,
345
+ BinderChannelCredentials channelCredentials ,
261
346
Executor mainThreadExecutor ,
262
347
ObjectPool <ScheduledExecutorService > scheduledExecutorPool ,
263
348
ObjectPool <? extends Executor > offloadExecutorPool ,
264
349
SecurityPolicy securityPolicy ,
350
+ @ Nullable UserHandle targetUserHandle ,
265
351
BindServiceFlags bindServiceFlags ,
266
352
InboundParcelablePolicy inboundParcelablePolicy ) {
267
353
this .sourceContext = sourceContext ;
354
+ this .channelCredentials = channelCredentials ;
268
355
this .mainThreadExecutor = mainThreadExecutor ;
269
356
this .scheduledExecutorPool = scheduledExecutorPool ;
270
357
this .offloadExecutorPool = offloadExecutorPool ;
271
358
this .securityPolicy = securityPolicy ;
359
+ this .targetUserHandle = targetUserHandle ;
272
360
this .bindServiceFlags = bindServiceFlags ;
273
361
this .inboundParcelablePolicy = inboundParcelablePolicy ;
274
362
@@ -284,7 +372,9 @@ public ConnectionClientTransport newClientTransport(
284
372
}
285
373
return new BinderTransport .BinderClientTransport (
286
374
sourceContext ,
375
+ channelCredentials ,
287
376
(AndroidComponentAddress ) addr ,
377
+ targetUserHandle ,
288
378
bindServiceFlags ,
289
379
mainThreadExecutor ,
290
380
scheduledExecutorPool ,
0 commit comments