Skip to content

Commit 14b243c

Browse files
committed
Add UserHandle and BinderChannelCredentials to BinderChannelBuilder to support cross-user ondevice server.
1 parent 017fb7f commit 14b243c

File tree

6 files changed

+69
-58
lines changed

6 files changed

+69
-58
lines changed

binder/src/main/java/io/grpc/binder/BinderChannelBuilder.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ public static BinderChannelBuilder forAddress(
7474
return new BinderChannelBuilder(
7575
checkNotNull(directAddress, "directAddress"),
7676
null,
77-
BinderChannelCredentials.forDefault(sourceContext));
77+
sourceContext,
78+
BinderChannelCredentials.forDefault());
7879
}
7980

8081
/**
@@ -90,16 +91,17 @@ public static BinderChannelBuilder forAddress(
9091
* resulting builder. They will not be shut down automatically.
9192
*
9293
* @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).
9395
* @param channelCredentials the arbitrary binder specific channel credentials to be used to
94-
* establish a binder connection including the context to bind from (e.g. The current
95-
* Activity or Application).
96+
* establish a binder connection.
9697
* @return a new builder
9798
*/
9899
public static BinderChannelBuilder forAddress(
99100
AndroidComponentAddress directAddress,
101+
Context sourceContext,
100102
BinderChannelCredentials channelCredentials) {
101103
return new BinderChannelBuilder(
102-
checkNotNull(directAddress, "directAddress"), null, channelCredentials);
104+
checkNotNull(directAddress, "directAddress"), null, sourceContext, channelCredentials);
103105
}
104106

105107
/**
@@ -123,7 +125,8 @@ public static BinderChannelBuilder forTarget(String target, Context sourceContex
123125
return new BinderChannelBuilder(
124126
null,
125127
checkNotNull(target, "target"),
126-
BinderChannelCredentials.forDefault(sourceContext));
128+
sourceContext,
129+
BinderChannelCredentials.forDefault());
127130
}
128131

129132
/**
@@ -140,15 +143,15 @@ public static BinderChannelBuilder forTarget(String target, Context sourceContex
140143
*
141144
* @param target A target uri which should resolve into an {@link AndroidComponentAddress}
142145
* referencing the service to bind to.
146+
* @param sourceContext the context to bind from (e.g. The current Activity or Application).
143147
* @param channelCredentials the arbitrary binder specific channel credentials to be used to
144-
* establish a binder connection including the context to bind from (e.g. The current
145-
* Activity or Application).
148+
* establish a binder connection.
146149
* @return a new builder
147150
*/
148151
public static BinderChannelBuilder forTarget(
149-
String target, BinderChannelCredentials channelCredentials) {
152+
String target, Context sourceContext, BinderChannelCredentials channelCredentials) {
150153
return new BinderChannelBuilder(
151-
null, checkNotNull(target, "target"), channelCredentials);
154+
null, checkNotNull(target, "target"), sourceContext, channelCredentials);
152155
}
153156

154157
/**
@@ -183,10 +186,10 @@ public static BinderChannelBuilder forTarget(String target) {
183186
private BinderChannelBuilder(
184187
@Nullable AndroidComponentAddress directAddress,
185188
@Nullable String target,
189+
Context sourceContext,
186190
BinderChannelCredentials channelCredentials) {
187191
mainThreadExecutor =
188-
ContextCompat.getMainExecutor(
189-
checkNotNull(channelCredentials.getSourceContext(), "sourceContext"));
192+
ContextCompat.getMainExecutor(checkNotNull(sourceContext, "sourceContext"));
190193
securityPolicy = SecurityPolicies.internalOnly();
191194
inboundParcelablePolicy = InboundParcelablePolicy.DEFAULT;
192195
bindServiceFlags = BindServiceFlags.DEFAULTS;
@@ -196,13 +199,14 @@ final class BinderChannelTransportFactoryBuilder
196199
@Override
197200
public ClientTransportFactory buildClientTransportFactory() {
198201
return new TransportFactory(
199-
channelCredentials,
202+
sourceContext,
200203
mainThreadExecutor,
201204
schedulerPool,
202205
managedChannelImplBuilder.getOffloadExecutorPool(),
203206
securityPolicy,
204207
bindServiceFlags,
205208
inboundParcelablePolicy,
209+
channelCredentials,
206210
targetUserHandle);
207211
}
208212
}
@@ -319,35 +323,38 @@ public BinderChannelBuilder idleTimeout(long value, TimeUnit unit) {
319323

320324
/** Creates new binder transports. */
321325
private static final class TransportFactory implements ClientTransportFactory {
322-
private final BinderChannelCredentials channelCredentials;
326+
private final Context sourceContext;
323327
private final Executor mainThreadExecutor;
324328
private final ObjectPool<ScheduledExecutorService> scheduledExecutorPool;
325329
private final ObjectPool<? extends Executor> offloadExecutorPool;
326330
private final SecurityPolicy securityPolicy;
327331
private final InboundParcelablePolicy inboundParcelablePolicy;
328332
private final BindServiceFlags bindServiceFlags;
333+
private final BinderChannelCredentials channelCredentials;
329334
@Nullable private final UserHandle targetUserHandle;
330335

331336
private ScheduledExecutorService executorService;
332337
private Executor offloadExecutor;
333338
private boolean closed;
334339

335340
TransportFactory(
336-
BinderChannelCredentials channelCredentials,
341+
Context sourceContext,
337342
Executor mainThreadExecutor,
338343
ObjectPool<ScheduledExecutorService> scheduledExecutorPool,
339344
ObjectPool<? extends Executor> offloadExecutorPool,
340345
SecurityPolicy securityPolicy,
341346
BindServiceFlags bindServiceFlags,
342347
InboundParcelablePolicy inboundParcelablePolicy,
348+
BinderChannelCredentials channelCredentials,
343349
@Nullable UserHandle targetUserHandle) {
344-
this.channelCredentials = channelCredentials;
350+
this.sourceContext = sourceContext;
345351
this.mainThreadExecutor = mainThreadExecutor;
346352
this.scheduledExecutorPool = scheduledExecutorPool;
347353
this.offloadExecutorPool = offloadExecutorPool;
348354
this.securityPolicy = securityPolicy;
349355
this.bindServiceFlags = bindServiceFlags;
350356
this.inboundParcelablePolicy = inboundParcelablePolicy;
357+
this.channelCredentials = channelCredentials;
351358
this.targetUserHandle = targetUserHandle;
352359

353360
executorService = scheduledExecutorPool.getObject();
@@ -361,9 +368,10 @@ public ConnectionClientTransport newClientTransport(
361368
throw new IllegalStateException("The transport factory is closed.");
362369
}
363370
return new BinderTransport.BinderClientTransport(
364-
channelCredentials,
371+
sourceContext,
365372
(AndroidComponentAddress) addr,
366373
bindServiceFlags,
374+
channelCredentials,
367375
targetUserHandle,
368376
mainThreadExecutor,
369377
scheduledExecutorPool,

binder/src/main/java/io/grpc/binder/BinderChannelCredentials.java

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
import static com.google.common.base.Preconditions.checkNotNull;
2020

2121
import android.content.ComponentName;
22-
import android.content.Context;
23-
import androidx.annotation.MainThread;
2422
import io.grpc.ChannelCredentials;
2523
import io.grpc.ExperimentalApi;
2624
import javax.annotation.Nullable;
@@ -32,35 +30,38 @@ public final class BinderChannelCredentials extends ChannelCredentials {
3230
/**
3331
* Creates the default BinderChannelCredentials.
3432
*
35-
* @param sourceContext the context to bind from (e.g. The current Activity or Application).
3633
* @return a BinderChannelCredentials
3734
*/
35+
<<<<<<< HEAD
3836
public static BinderChannelCredentials forDefault(Context sourceContext) {
3937
return new BinderChannelCredentials(checkNotNull(sourceContext, "sourceContext"), null);
38+
=======
39+
public static BinderChannelCredentials forDefault() {
40+
return new BinderChannelCredentials(null);
41+
>>>>>>> 2b7f83473 (Add UserHandle and BinderChannelCredentials to BinderChannelBuilder to support cross-user ondevice server.)
4042
}
4143

4244
/**
4345
* Creates a BinderChannelCredentials to be used with DevicePolicyManager API.
4446
*
45-
* @param sourceContext the context to bind from (e.g. The current Activity or Application).
4647
* @param devicePolicyAdminComponentName the admin component to be specified with
4748
* DevicePolicyManager.bindDeviceAdminServiceAsUser API.
4849
* @return a BinderChannelCredentials
4950
*/
5051
public static BinderChannelCredentials forDevicePolicyAdmin(
52+
<<<<<<< HEAD
5153
Context sourceContext, ComponentName devicePolicyAdminComponentName) {
5254
return new BinderChannelCredentials(
5355
checkNotNull(sourceContext, "sourceContext"), devicePolicyAdminComponentName);
56+
=======
57+
ComponentName devicePolicyAdminComponentName) {
58+
return new BinderChannelCredentials(devicePolicyAdminComponentName);
59+
>>>>>>> 2b7f83473 (Add UserHandle and BinderChannelCredentials to BinderChannelBuilder to support cross-user ondevice server.)
5460
}
5561

56-
// The sourceContext field is intentionally not guarded, since (aside from the constructor),
57-
// it is only modified in the main thread.
58-
@Nullable private Context sourceContext; // Only null in the unbound state.
5962
@Nullable private final ComponentName devicePolicyAdminComponentName;
6063

61-
private BinderChannelCredentials(
62-
Context sourceContext, @Nullable ComponentName devicePolicyAdminComponentName) {
63-
this.sourceContext = sourceContext;
64+
private BinderChannelCredentials(@Nullable ComponentName devicePolicyAdminComponentName) {
6465
this.devicePolicyAdminComponentName = devicePolicyAdminComponentName;
6566
}
6667

@@ -69,18 +70,8 @@ public ChannelCredentials withoutBearerTokens() {
6970
return this;
7071
}
7172

72-
@Nullable
73-
public Context getSourceContext() {
74-
return sourceContext;
75-
}
76-
7773
@Nullable
7874
public ComponentName getDevicePolicyAdminComponentName() {
7975
return devicePolicyAdminComponentName;
8076
}
81-
82-
@MainThread
83-
public void clearReferences() {
84-
sourceContext = null;
85-
}
8677
}

binder/src/main/java/io/grpc/binder/internal/BinderTransport.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,10 @@ public static final class BinderClientTransport extends BinderTransport
569569
private int latestCallId = FIRST_CALL_ID;
570570

571571
public BinderClientTransport(
572-
BinderChannelCredentials channelCredentials,
572+
Context sourceContext,
573573
AndroidComponentAddress targetAddress,
574574
BindServiceFlags bindServiceFlags,
575+
BinderChannelCredentials channelCredentials,
575576
@Nullable UserHandle targetUserHandle,
576577
Executor mainThreadExecutor,
577578
ObjectPool<ScheduledExecutorService> executorServicePool,
@@ -581,9 +582,8 @@ public BinderClientTransport(
581582
Attributes eagAttrs) {
582583
super(
583584
executorServicePool,
584-
buildClientAttributes(
585-
eagAttrs, channelCredentials.getSourceContext(), targetAddress, inboundParcelablePolicy),
586-
buildLogId(channelCredentials.getSourceContext(), targetAddress));
585+
buildClientAttributes(eagAttrs, sourceContext, targetAddress, inboundParcelablePolicy),
586+
buildLogId(sourceContext, targetAddress));
587587
this.offloadExecutorPool = offloadExecutorPool;
588588
this.securityPolicy = securityPolicy;
589589
this.offloadExecutor = offloadExecutorPool.getObject();
@@ -593,9 +593,10 @@ public BinderClientTransport(
593593
serviceBinding =
594594
new ServiceBinding(
595595
mainThreadExecutor,
596-
channelCredentials,
596+
sourceContext,
597597
targetAddress.asBindIntent(),
598598
bindServiceFlags.toInteger(),
599+
channelCredentials,
599600
targetUserHandle,
600601
this);
601602
}

binder/src/main/java/io/grpc/binder/internal/ServiceBinding.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public String methodName() {
8080

8181
private final Intent bindIntent;
8282
private final int bindFlags;
83+
private final BinderChannelCredentials channelCredentials;
8384
private final Observer observer;
8485
private final Executor mainThreadExecutor;
8586
@Nullable private final UserHandle targetUserHandle;
@@ -91,16 +92,17 @@ public String methodName() {
9192
// they're only modified in the main thread. The constructor contains a synchronized block
9293
// to ensure there's a write barrier when these fields are first written.
9394

94-
@Nullable private BinderChannelCredentials channelCredentials; // Only null in the unbound state.
95+
@Nullable private Context sourceContext; // Only null in the unbound state.
9596

9697
private State reportedState; // Only used on the main thread.
9798

9899
@AnyThread
99100
ServiceBinding(
100101
Executor mainThreadExecutor,
101-
BinderChannelCredentials channelCredentials,
102+
Context sourceContext,
102103
Intent bindIntent,
103104
int bindFlags,
105+
BinderChannelCredentials channelCredentials,
104106
@Nullable UserHandle targetUserHandle,
105107
Observer observer) {
106108
// We need to synchronize here ensure other threads see all
@@ -109,8 +111,9 @@ public String methodName() {
109111
this.bindIntent = bindIntent;
110112
this.bindFlags = bindFlags;
111113
this.observer = observer;
112-
this.channelCredentials = channelCredentials;
114+
this.sourceContext = sourceContext;
113115
this.mainThreadExecutor = mainThreadExecutor;
116+
this.channelCredentials = channelCredentials;
114117
this.targetUserHandle = targetUserHandle;
115118
state = State.NOT_BINDING;
116119
reportedState = State.NOT_BINDING;
@@ -143,22 +146,28 @@ public synchronized void bind() {
143146
if (state == State.NOT_BINDING) {
144147
state = State.BINDING;
145148
Status bindResult =
146-
bindInternal(channelCredentials, bindIntent, this, bindFlags, targetUserHandle);
149+
bindInternal(
150+
sourceContext,
151+
bindIntent,
152+
this,
153+
bindFlags,
154+
channelCredentials,
155+
targetUserHandle);
147156
if (!bindResult.isOk()) {
148-
handleBindServiceFailure(channelCredentials.getSourceContext(), this);
157+
handleBindServiceFailure(sourceContext, this);
149158
state = State.UNBOUND;
150159
mainThreadExecutor.execute(() -> notifyUnbound(bindResult));
151160
}
152161
}
153162
}
154163

155164
private static Status bindInternal(
156-
BinderChannelCredentials channelCredentials,
165+
Context context,
157166
Intent bindIntent,
158167
ServiceConnection conn,
159168
int flags,
169+
BinderChannelCredentials channelCredentials,
160170
@Nullable UserHandle targetUserHandle) {
161-
Context context = channelCredentials.getSourceContext();
162171
BindMethodType bindMethodType = BindMethodType.BIND_SERVICE;
163172
try {
164173
if (targetUserHandle == null) {
@@ -231,7 +240,7 @@ void unbindInternal(Status reason) {
231240
Context unbindFrom = null;
232241
synchronized (this) {
233242
if (state == State.BINDING || state == State.BOUND) {
234-
unbindFrom = channelCredentials.getSourceContext();
243+
unbindFrom = sourceContext;
235244
}
236245
state = State.UNBOUND;
237246
}
@@ -243,7 +252,7 @@ void unbindInternal(Status reason) {
243252

244253
@MainThread
245254
private void clearReferences() {
246-
channelCredentials = null;
255+
sourceContext = null;
247256
}
248257

249258
@Override
@@ -283,6 +292,6 @@ public void onBindingDied(ComponentName name) {
283292

284293
@VisibleForTesting
285294
synchronized boolean isSourceContextCleared() {
286-
return channelCredentials == null;
295+
return sourceContext == null;
287296
}
288297
}

binder/src/test/java/io/grpc/binder/BinderChannelCredentialsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class BinderChannelCredentialsTest {
1515

1616
@Test
1717
public void defaultBinderChannelCredentials() {
18-
BinderChannelCredentials channelCredentials = BinderChannelCredentials.forDefault(appContext);
18+
BinderChannelCredentials channelCredentials = BinderChannelCredentials.forDefault();
1919
assertThat(channelCredentials.getDevicePolicyAdminComponentName()).isNull();
2020
}
2121

@@ -24,7 +24,7 @@ public void binderChannelCredentialsForDevicePolicyAdmin() {
2424
String deviceAdminClassName = "DevicePolicyAdmin";
2525
BinderChannelCredentials channelCredentials =
2626
BinderChannelCredentials.forDevicePolicyAdmin(
27-
appContext, new ComponentName(appContext, deviceAdminClassName));
27+
new ComponentName(appContext, deviceAdminClassName));
2828
assertThat(channelCredentials.getDevicePolicyAdminComponentName()).isNotNull();
2929
assertThat(channelCredentials.getDevicePolicyAdminComponentName().getClassName())
3030
.isEqualTo(deviceAdminClassName);

0 commit comments

Comments
 (0)