Skip to content

Commit a685c7a

Browse files
committed
Add UserHandle and BinderChannelCredentials to BinderChannelBuilder to support cross-user ondevice server.
1 parent 19de143 commit a685c7a

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

binder/src/test/java/io/grpc/binder/internal/ServiceBindingTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.robolectric.annotation.LooperMode.Mode.PAUSED;
2525

2626
import android.app.Application;
27+
import android.app.admin.DevicePolicyManager;
2728
import android.content.ComponentName;
2829
import android.content.Context;
2930
import android.content.Intent;
@@ -32,6 +33,7 @@
3233
import androidx.test.core.app.ApplicationProvider;
3334
import io.grpc.Status;
3435
import io.grpc.Status.Code;
36+
import io.grpc.binder.BinderChannelCredentials;
3537
import io.grpc.binder.internal.Bindable.Observer;
3638
import org.junit.Before;
3739
import org.junit.Rule;
@@ -44,6 +46,7 @@
4446
import org.robolectric.annotation.Config;
4547
import org.robolectric.annotation.LooperMode;
4648
import org.robolectric.shadows.ShadowApplication;
49+
import org.robolectric.shadows.ShadowDevicePolicyManager;
4750

4851
@LooperMode(PAUSED)
4952
@RunWith(RobolectricTestRunner.class)
@@ -256,6 +259,45 @@ public void testCallsAfterUnbindDontCrash() throws Exception {
256259
shadowOf(getMainLooper()).idle();
257260
}
258261

262+
@Test
263+
public void testBindWithTargetUserHandle() throws Exception {
264+
binding =
265+
newBuilder().setTargetUserHandle(UserHandle.getUserHandleForUid(/* userId= */ 0)).build();
266+
shadowOf(getMainLooper()).idle();
267+
268+
binding.bind();
269+
shadowOf(getMainLooper()).idle();
270+
271+
assertThat(shadowApplication.getBoundServiceConnections()).isNotEmpty();
272+
assertThat(observer.gotBoundEvent).isTrue();
273+
assertThat(observer.binder).isSameInstanceAs(mockBinder);
274+
assertThat(observer.gotUnboundEvent).isFalse();
275+
assertThat(binding.isSourceContextCleared()).isFalse();
276+
}
277+
278+
@Test
279+
public void testBindWithDeviceAdmin() throws Exception {
280+
String deviceAdminClassName = "DevicePolicyAdmin";
281+
ComponentName adminComponent = new ComponentName(appContext, deviceAdminClassName);
282+
allowBindDeviceAdminForUser(appContext, adminComponent, /* userId= */ 0);
283+
binding =
284+
newBuilder()
285+
.setTargetUserHandle(UserHandle.getUserHandleForUid(/* userId= */ 0))
286+
.setChannelCredentials(
287+
BinderChannelCredentials.forDevicePolicyAdmin(appContext, adminComponent))
288+
.build();
289+
shadowOf(getMainLooper()).idle();
290+
291+
binding.bind();
292+
shadowOf(getMainLooper()).idle();
293+
294+
assertThat(shadowApplication.getBoundServiceConnections()).isNotEmpty();
295+
assertThat(observer.gotBoundEvent).isTrue();
296+
assertThat(observer.binder).isSameInstanceAs(mockBinder);
297+
assertThat(observer.gotUnboundEvent).isFalse();
298+
assertThat(binding.isSourceContextCleared()).isFalse();
299+
}
300+
259301
private void assertNoLockHeld() {
260302
try {
261303
binding.wait(1);
@@ -268,6 +310,14 @@ private void assertNoLockHeld() {
268310
}
269311
}
270312

313+
private static void allowBindDeviceAdminForUser(Context context, ComponentName admin, int userId) {
314+
ShadowDevicePolicyManager devicePolicyManager =
315+
shadowOf(context.getSystemService(DevicePolicyManager.class));
316+
devicePolicyManager.setDeviceOwner(admin);
317+
devicePolicyManager.setBindDeviceAdminTargetUsers(
318+
Arrays.asList(UserHandle.getUserHandleForUid(userId)));
319+
}
320+
271321
private class TestObserver implements Bindable.Observer {
272322

273323
public boolean gotBoundEvent;
@@ -298,9 +348,12 @@ private static class ServiceBindingBuilder {
298348
private Observer observer;
299349
private Intent bindIntent = new Intent();
300350
private int bindServiceFlags;
351+
@Nullable private UserHandle targetUserHandle = null;
352+
private BinderChannelCredentials channelCredentials;
301353

302354
public ServiceBindingBuilder setSourceContext(Context sourceContext) {
303355
this.sourceContext = sourceContext;
356+
this.channelCredentials = BinderChannelCredentials.forDefault(sourceContext);
304357
return this;
305358
}
306359

@@ -324,12 +377,25 @@ public ServiceBindingBuilder setObserver(Observer observer) {
324377
return this;
325378
}
326379

380+
public ServiceBindingBuilder setTargetUserHandle(UserHandle targetUserHandle) {
381+
this.targetUserHandle = targetUserHandle;
382+
return this;
383+
}
384+
385+
public ServiceBindingBuilder setChannelCredentials(
386+
BinderChannelCredentials channelCredentials) {
387+
this.channelCredentials = channelCredentials;
388+
return this;
389+
}
390+
327391
public ServiceBinding build() {
328392
return new ServiceBinding(
329393
ContextCompat.getMainExecutor(sourceContext),
330394
sourceContext,
331395
bindIntent,
332396
bindServiceFlags,
397+
channelCredentials,
398+
targetUserHandle,
333399
observer);
334400
}
335401
}

0 commit comments

Comments
 (0)