1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertThrows;
22 import static org.junit.Assert.assertTrue;
23 
24 import android.platform.test.annotations.Presubmit;
25 
26 import androidx.test.runner.AndroidJUnit4;
27 
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 @Presubmit
32 @RunWith(AndroidJUnit4.class)
33 public class ParcelTest {
34     private static final int WORK_SOURCE_1 = 1000;
35     private static final int WORK_SOURCE_2 = 1002;
36     private static final String INTERFACE_TOKEN_1 = "IBinder interface token";
37     private static final String INTERFACE_TOKEN_2 = "Another IBinder interface token";
38 
39     @Test
testIsForRpc()40     public void testIsForRpc() {
41         Parcel p = Parcel.obtain();
42         assertEquals(false, p.isForRpc());
43         p.recycle();
44     }
45 
46     @Test
testCallingWorkSourceUidAfterWrite()47     public void testCallingWorkSourceUidAfterWrite() {
48         Parcel p = Parcel.obtain();
49         // Method does not throw if replaceCallingWorkSourceUid is called before requests headers
50         // are added.
51         assertEquals(false, p.replaceCallingWorkSourceUid(WORK_SOURCE_1));
52         assertEquals(Binder.UNSET_WORKSOURCE, p.readCallingWorkSourceUid());
53 
54         // WorkSource can be updated.
55         p.writeInterfaceToken(INTERFACE_TOKEN_1);
56         assertEquals(true, p.replaceCallingWorkSourceUid(WORK_SOURCE_2));
57         assertEquals(WORK_SOURCE_2, p.readCallingWorkSourceUid());
58 
59         // WorkSource can be updated to unset value.
60         assertEquals(true, p.replaceCallingWorkSourceUid(Binder.UNSET_WORKSOURCE));
61         assertEquals(Binder.UNSET_WORKSOURCE, p.readCallingWorkSourceUid());
62 
63         p.recycle();
64     }
65 
66     @Test
testCallingWorkSourceUidAfterEnforce()67     public void testCallingWorkSourceUidAfterEnforce() {
68         Parcel p = Parcel.obtain();
69         p.writeInterfaceToken(INTERFACE_TOKEN_1);
70         assertEquals(true, p.replaceCallingWorkSourceUid(WORK_SOURCE_1));
71         p.setDataPosition(0);
72 
73         p.enforceInterface(INTERFACE_TOKEN_1);
74         assertEquals(WORK_SOURCE_1, p.readCallingWorkSourceUid());
75 
76         // WorkSource can be updated.
77         assertEquals(true, p.replaceCallingWorkSourceUid(WORK_SOURCE_2));
78         assertEquals(WORK_SOURCE_2, p.readCallingWorkSourceUid());
79 
80         p.recycle();
81     }
82 
83     @Test
testParcelWithMultipleHeaders()84     public void testParcelWithMultipleHeaders() {
85         Parcel p = Parcel.obtain();
86         Binder.setCallingWorkSourceUid(WORK_SOURCE_1);
87         p.writeInterfaceToken(INTERFACE_TOKEN_1);
88         Binder.setCallingWorkSourceUid(WORK_SOURCE_2);
89         p.writeInterfaceToken(INTERFACE_TOKEN_2);
90         p.setDataPosition(0);
91 
92         // WorkSource is from the first header.
93         p.enforceInterface(INTERFACE_TOKEN_1);
94         assertEquals(WORK_SOURCE_1, p.readCallingWorkSourceUid());
95         p.enforceInterface(INTERFACE_TOKEN_2);
96         assertEquals(WORK_SOURCE_1, p.readCallingWorkSourceUid());
97 
98         p.recycle();
99     }
100 
101     /**
102      * Verify that writing/reading UTF-8 and UTF-16 strings works well.
103      */
104     @Test
testStrings()105     public void testStrings() {
106         final String[] strings = {
107                 null, "", "abc\0def", "com.example.typical_package_name",
108                 "從不喜歡孤單一個 - 蘇永康/吳雨霏", "example"
109         };
110 
111         final Parcel p = Parcel.obtain();
112         for (String string : strings) {
113             p.writeString8(string);
114             p.writeString16(string);
115         }
116 
117         p.setDataPosition(0);
118         for (String string : strings) {
119             assertEquals(string, p.readString8());
120             assertEquals(string, p.readString16());
121         }
122     }
123 
124     @Test
testCompareDataInRange_whenSameData()125     public void testCompareDataInRange_whenSameData() {
126         Parcel pA = Parcel.obtain();
127         int iA = pA.dataPosition();
128         pA.writeInt(13);
129         pA.writeString("Tiramisu");
130         int length = pA.dataPosition() - iA;
131         Parcel pB = Parcel.obtain();
132         pB.writeString("Prefix");
133         int iB = pB.dataPosition();
134         pB.writeInt(13);
135         pB.writeString("Tiramisu");
136 
137         assertTrue(Parcel.compareData(pA, iA, pB, iB, length));
138     }
139 
140     @Test
testCompareDataInRange_whenSameDataWithBinder()141     public void testCompareDataInRange_whenSameDataWithBinder() {
142         Binder binder = new Binder();
143         Parcel pA = Parcel.obtain();
144         int iA = pA.dataPosition();
145         pA.writeInt(13);
146         pA.writeStrongBinder(binder);
147         pA.writeString("Tiramisu");
148         int length = pA.dataPosition() - iA;
149         Parcel pB = Parcel.obtain();
150         pB.writeString("Prefix");
151         int iB = pB.dataPosition();
152         pB.writeInt(13);
153         pB.writeStrongBinder(binder);
154         pB.writeString("Tiramisu");
155 
156         assertTrue(Parcel.compareData(pA, iA, pB, iB, length));
157     }
158 
159     @Test
testCompareDataInRange_whenDifferentData()160     public void testCompareDataInRange_whenDifferentData() {
161         Parcel pA = Parcel.obtain();
162         int iA = pA.dataPosition();
163         pA.writeInt(13);
164         pA.writeString("Tiramisu");
165         int length = pA.dataPosition() - iA;
166         Parcel pB = Parcel.obtain();
167         int iB = pB.dataPosition();
168         pB.writeString("Prefix");
169         pB.writeInt(13);
170         pB.writeString("Tiramisu");
171 
172         assertFalse(Parcel.compareData(pA, iA, pB, iB, length));
173     }
174 
175     @Test
testCompareDataInRange_whenLimitOutOfBounds_throws()176     public void testCompareDataInRange_whenLimitOutOfBounds_throws() {
177         Parcel pA = Parcel.obtain();
178         int iA = pA.dataPosition();
179         pA.writeInt(12);
180         pA.writeString("Tiramisu");
181         int length = pA.dataPosition() - iA;
182         Parcel pB = Parcel.obtain();
183         pB.writeString("Prefix");
184         int iB = pB.dataPosition();
185         pB.writeInt(13);
186         pB.writeString("Tiramisu");
187         pB.writeInt(-1);
188 
189         assertThrows(IllegalArgumentException.class,
190                 () -> Parcel.compareData(pA, iA + length, pB, iB, 1));
191         assertThrows(IllegalArgumentException.class,
192                 () -> Parcel.compareData(pA, iA, pB, pB.dataSize(), 1));
193         assertThrows(IllegalArgumentException.class,
194                 () -> Parcel.compareData(pA, iA, pB, iB, length + 1));
195         assertThrows(IllegalArgumentException.class,
196                 () -> Parcel.compareData(pA, iA + length + 1, pB, iB, 0));
197         assertThrows(IllegalArgumentException.class,
198                 () -> Parcel.compareData(pA, iA, pB, iB + pB.dataSize() + 1, 0));
199     }
200 
201     @Test
testCompareDataInRange_whenLengthZero()202     public void testCompareDataInRange_whenLengthZero() {
203         Parcel pA = Parcel.obtain();
204         int iA = pA.dataPosition();
205         pA.writeInt(12);
206         pA.writeString("Tiramisu");
207         int length = pA.dataPosition() - iA;
208         Parcel pB = Parcel.obtain();
209         pB.writeString("Prefix");
210         int iB = pB.dataPosition();
211         pB.writeInt(13);
212         pB.writeString("Tiramisu");
213 
214         assertTrue(Parcel.compareData(pA, 0, pB, iB, 0));
215         assertTrue(Parcel.compareData(pA, iA + length, pB, iB, 0));
216         assertTrue(Parcel.compareData(pA, iA, pB, pB.dataSize(), 0));
217     }
218 
219     @Test
testCompareDataInRange_whenNegativeLength_throws()220     public void testCompareDataInRange_whenNegativeLength_throws() {
221         Parcel pA = Parcel.obtain();
222         int iA = pA.dataPosition();
223         pA.writeInt(12);
224         pA.writeString("Tiramisu");
225         Parcel pB = Parcel.obtain();
226         pB.writeString("Prefix");
227         int iB = pB.dataPosition();
228         pB.writeInt(13);
229         pB.writeString("Tiramisu");
230 
231         assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, iA, pB, iB, -1));
232     }
233 
234     @Test
testCompareDataInRange_whenNegativeOffset_throws()235     public void testCompareDataInRange_whenNegativeOffset_throws() {
236         Parcel pA = Parcel.obtain();
237         int iA = pA.dataPosition();
238         pA.writeInt(12);
239         pA.writeString("Tiramisu");
240         Parcel pB = Parcel.obtain();
241         pB.writeString("Prefix");
242         int iB = pB.dataPosition();
243         pB.writeInt(13);
244         pB.writeString("Tiramisu");
245 
246         assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, -1, pB, iB, 0));
247         assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, 0, pB, -1, 0));
248     }
249 }
250