24
24
import static org .robolectric .annotation .LooperMode .Mode .PAUSED ;
25
25
26
26
import android .app .Application ;
27
+ import android .app .admin .DevicePolicyManager ;
27
28
import android .content .ComponentName ;
28
29
import android .content .Context ;
29
30
import android .content .Intent ;
32
33
import androidx .test .core .app .ApplicationProvider ;
33
34
import io .grpc .Status ;
34
35
import io .grpc .Status .Code ;
36
+ import io .grpc .binder .BinderChannelCredentials ;
35
37
import io .grpc .binder .internal .Bindable .Observer ;
36
38
import org .junit .Before ;
37
39
import org .junit .Rule ;
44
46
import org .robolectric .annotation .Config ;
45
47
import org .robolectric .annotation .LooperMode ;
46
48
import org .robolectric .shadows .ShadowApplication ;
49
+ import org .robolectric .shadows .ShadowDevicePolicyManager ;
47
50
48
51
@ LooperMode (PAUSED )
49
52
@ RunWith (RobolectricTestRunner .class )
@@ -256,6 +259,45 @@ public void testCallsAfterUnbindDontCrash() throws Exception {
256
259
shadowOf (getMainLooper ()).idle ();
257
260
}
258
261
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
+
259
301
private void assertNoLockHeld () {
260
302
try {
261
303
binding .wait (1 );
@@ -268,6 +310,14 @@ private void assertNoLockHeld() {
268
310
}
269
311
}
270
312
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
+
271
321
private class TestObserver implements Bindable .Observer {
272
322
273
323
public boolean gotBoundEvent ;
@@ -298,9 +348,12 @@ private static class ServiceBindingBuilder {
298
348
private Observer observer ;
299
349
private Intent bindIntent = new Intent ();
300
350
private int bindServiceFlags ;
351
+ @ Nullable private UserHandle targetUserHandle = null ;
352
+ private BinderChannelCredentials channelCredentials ;
301
353
302
354
public ServiceBindingBuilder setSourceContext (Context sourceContext ) {
303
355
this .sourceContext = sourceContext ;
356
+ this .channelCredentials = BinderChannelCredentials .forDefault (sourceContext );
304
357
return this ;
305
358
}
306
359
@@ -324,12 +377,25 @@ public ServiceBindingBuilder setObserver(Observer observer) {
324
377
return this ;
325
378
}
326
379
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
+
327
391
public ServiceBinding build () {
328
392
return new ServiceBinding (
329
393
ContextCompat .getMainExecutor (sourceContext ),
330
394
sourceContext ,
331
395
bindIntent ,
332
396
bindServiceFlags ,
397
+ channelCredentials ,
398
+ targetUserHandle ,
333
399
observer );
334
400
}
335
401
}
0 commit comments