1package org.robolectric.shadows;
2
3import static org.assertj.core.api.Assertions.assertThat;
4import static org.junit.Assert.assertTrue;
5import static org.junit.Assert.fail;
6
7import android.os.Binder;
8import android.os.Parcel;
9import android.os.RemoteException;
10import org.junit.Test;
11import org.junit.runner.RunWith;
12import org.robolectric.RobolectricTestRunner;
13
14@RunWith(RobolectricTestRunner.class)
15public class ShadowBinderTest {
16  @Test
17  public void transactCallsOnTransact() throws Exception {
18    TestBinder testBinder = new TestBinder();
19    Parcel data = Parcel.obtain();
20    Parcel reply = Parcel.obtain();
21    data.writeString("Hello Robolectric");
22    assertTrue(testBinder.transact(2, data, reply, 3));
23    assertThat(testBinder.code).isEqualTo(2);
24    assertThat(testBinder.data).isSameAs(data);
25    assertThat(testBinder.reply).isSameAs(reply);
26    assertThat(testBinder.flags).isEqualTo(3);
27    reply.readException();
28    assertThat(reply.readString()).isEqualTo("Hello Robolectric");
29  }
30
31  static class TestBinder extends Binder {
32    int code;
33    Parcel data;
34    Parcel reply;
35    int flags;
36
37    @Override
38    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
39      this.code = code;
40      this.data = data;
41      this.reply = reply;
42      this.flags = flags;
43      String string = data.readString();
44      reply.writeNoException();
45      reply.writeString(string);
46      return true;
47    }
48  }
49
50  @Test
51  public void thrownExceptionIsParceled() throws Exception {
52    TestThrowingBinder testThrowingBinder = new TestThrowingBinder();
53    Parcel data = Parcel.obtain();
54    Parcel reply = Parcel.obtain();
55    testThrowingBinder.transact(2, data, reply, 3);
56    try {
57      reply.readException();
58      fail();  // Expect thrown
59    } catch (SecurityException e) {
60      assertThat(e.getMessage()).isEqualTo("Halt! Who goes there?");
61    }
62  }
63
64  static class TestThrowingBinder extends Binder {
65
66    @Override
67    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
68      throw new SecurityException("Halt! Who goes there?");
69    }
70  }
71
72  @Test
73  public void testSetCallingUid() {
74    ShadowBinder.setCallingUid(37);
75    assertThat(Binder.getCallingUid()).isEqualTo(37);
76  }
77
78  @Test
79  public void testSetCallingPid() {
80    ShadowBinder.setCallingPid(25);
81    assertThat(Binder.getCallingPid()).isEqualTo(25);
82  }
83
84  @Test
85  public void testGetCallingUidShouldUseProcessUidByDefault() {
86    assertThat(Binder.getCallingUid()).isEqualTo(android.os.Process.myUid());
87  }
88
89  @Test
90  public void testGetCallingPidShouldUseProcessPidByDefault() {
91    assertThat(Binder.getCallingPid()).isEqualTo(android.os.Process.myPid());
92  }
93
94  @Test
95  public void testResetUpdatesCallingUidAndPid() {
96    ShadowBinder.setCallingPid(48);
97    ShadowBinder.setCallingUid(49);
98    ShadowBinder.reset();
99    assertThat(Binder.getCallingPid()).isEqualTo(android.os.Process.myPid());
100    assertThat(Binder.getCallingUid()).isEqualTo(android.os.Process.myUid());
101  }
102}
103