1 /*
2 * Copyright (C) 2020, 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 //! Test Rust client for the AIDL compiler.
18
19 use aidl_test_interface::aidl::android::aidl::tests::INewName::{self, BpNewName};
20 use aidl_test_interface::aidl::android::aidl::tests::IOldName::{self, BpOldName};
21 use aidl_test_interface::aidl::android::aidl::tests::ITestService::{
22 self, BpTestService, ITestServiceDefault, ITestServiceDefaultRef,
23 };
24 use aidl_test_interface::aidl::android::aidl::tests::{
25 BackendType::BackendType, ByteEnum::ByteEnum, IntEnum::IntEnum, LongEnum::LongEnum, StructuredParcelable, Union,
26 };
27 use aidl_test_interface::aidl::android::aidl::tests::unions::{
28 EnumUnion::EnumUnion,
29 };
30 use aidl_test_interface::binder;
31 use aidl_test_versioned_interface::aidl::android::aidl::versioned::tests::{
32 IFooInterface, IFooInterface::BpFooInterface, BazUnion::BazUnion,
33 };
34 use std::fs::File;
35 use std::io::{Read, Write};
36 use std::os::unix::io::FromRawFd;
37 use std::sync::Arc;
38
get_test_service() -> binder::Strong<dyn ITestService::ITestService>39 fn get_test_service() -> binder::Strong<dyn ITestService::ITestService> {
40 binder::get_interface(<BpTestService as ITestService::ITestService>::get_descriptor())
41 .expect("did not get binder service")
42 }
43
44 #[test]
test_constants()45 fn test_constants() {
46 assert_eq!(ITestService::A1, 1);
47 assert_eq!(ITestService::A2, 1);
48 assert_eq!(ITestService::A3, 1);
49 assert_eq!(ITestService::A4, 1);
50 assert_eq!(ITestService::A5, 1);
51 assert_eq!(ITestService::A6, 1);
52 assert_eq!(ITestService::A7, 1);
53 assert_eq!(ITestService::A8, 1);
54 assert_eq!(ITestService::A9, 1);
55 assert_eq!(ITestService::A10, 1);
56 assert_eq!(ITestService::A11, 1);
57 assert_eq!(ITestService::A12, 1);
58 assert_eq!(ITestService::A13, 1);
59 assert_eq!(ITestService::A14, 1);
60 assert_eq!(ITestService::A15, 1);
61 assert_eq!(ITestService::A16, 1);
62 assert_eq!(ITestService::A17, 1);
63 assert_eq!(ITestService::A18, 1);
64 assert_eq!(ITestService::A19, 1);
65 assert_eq!(ITestService::A20, 1);
66 assert_eq!(ITestService::A21, 1);
67 assert_eq!(ITestService::A22, 1);
68 assert_eq!(ITestService::A23, 1);
69 assert_eq!(ITestService::A24, 1);
70 assert_eq!(ITestService::A25, 1);
71 assert_eq!(ITestService::A26, 1);
72 assert_eq!(ITestService::A27, 1);
73 assert_eq!(ITestService::A28, 1);
74 assert_eq!(ITestService::A29, 1);
75 assert_eq!(ITestService::A30, 1);
76 assert_eq!(ITestService::A31, 1);
77 assert_eq!(ITestService::A32, 1);
78 assert_eq!(ITestService::A33, 1);
79 assert_eq!(ITestService::A34, 1);
80 assert_eq!(ITestService::A35, 1);
81 assert_eq!(ITestService::A36, 1);
82 assert_eq!(ITestService::A37, 1);
83 assert_eq!(ITestService::A38, 1);
84 assert_eq!(ITestService::A39, 1);
85 assert_eq!(ITestService::A40, 1);
86 assert_eq!(ITestService::A41, 1);
87 assert_eq!(ITestService::A42, 1);
88 assert_eq!(ITestService::A43, 1);
89 assert_eq!(ITestService::A44, 1);
90 assert_eq!(ITestService::A45, 1);
91 assert_eq!(ITestService::A46, 1);
92 assert_eq!(ITestService::A47, 1);
93 assert_eq!(ITestService::A48, 1);
94 assert_eq!(ITestService::A49, 1);
95 assert_eq!(ITestService::A50, 1);
96 assert_eq!(ITestService::A51, 1);
97 assert_eq!(ITestService::A52, 1);
98 assert_eq!(ITestService::A53, 1);
99 assert_eq!(ITestService::A54, 1);
100 assert_eq!(ITestService::A55, 1);
101 assert_eq!(ITestService::A56, 1);
102 assert_eq!(ITestService::A57, 1);
103 }
104
105 #[test]
test_oneway()106 fn test_oneway() {
107 let result = get_test_service().TestOneway();
108 assert_eq!(result, Ok(()));
109 }
110
111 macro_rules! test_primitive {
112 ($test:ident, $func:ident, $value:expr) => {
113 #[test]
114 fn $test() {
115 let value = $value;
116 let result = get_test_service().$func(value);
117 assert_eq!(result, Ok(value));
118 }
119 };
120 }
121
122 test_primitive! {test_primitive_bool_false, RepeatBoolean, false}
123 test_primitive! {test_primitive_bool_true, RepeatBoolean, true}
124 test_primitive! {test_primitive_byte, RepeatByte, -128i8}
125 test_primitive! {test_primitive_char, RepeatChar, 'A' as u16}
126 test_primitive! {test_primitive_int, RepeatInt, 1i32 << 30}
127 test_primitive! {test_primitive_long, RepeatLong, 1i64 << 60}
128 test_primitive! {test_primitive_float, RepeatFloat, 1.0f32 / 3.0f32}
129 test_primitive! {test_primitive_double, RepeatDouble, 1.0f64 / 3.0f64}
130 test_primitive! {test_primitive_byte_constant, RepeatByte, ITestService::BYTE_TEST_CONSTANT}
131 test_primitive! {test_primitive_constant1, RepeatInt, ITestService::TEST_CONSTANT}
132 test_primitive! {test_primitive_constant2, RepeatInt, ITestService::TEST_CONSTANT2}
133 test_primitive! {test_primitive_constant3, RepeatInt, ITestService::TEST_CONSTANT3}
134 test_primitive! {test_primitive_constant4, RepeatInt, ITestService::TEST_CONSTANT4}
135 test_primitive! {test_primitive_constant5, RepeatInt, ITestService::TEST_CONSTANT5}
136 test_primitive! {test_primitive_constant6, RepeatInt, ITestService::TEST_CONSTANT6}
137 test_primitive! {test_primitive_constant7, RepeatInt, ITestService::TEST_CONSTANT7}
138 test_primitive! {test_primitive_constant8, RepeatInt, ITestService::TEST_CONSTANT8}
139 test_primitive! {test_primitive_constant9, RepeatInt, ITestService::TEST_CONSTANT9}
140 test_primitive! {test_primitive_constant10, RepeatInt, ITestService::TEST_CONSTANT10}
141 test_primitive! {test_primitive_constant11, RepeatInt, ITestService::TEST_CONSTANT11}
142 test_primitive! {test_primitive_constant12, RepeatInt, ITestService::TEST_CONSTANT12}
143 test_primitive! {test_primitive_long_constant, RepeatLong, ITestService::LONG_TEST_CONSTANT}
144 test_primitive! {test_primitive_byte_enum, RepeatByteEnum, ByteEnum::FOO}
145 test_primitive! {test_primitive_int_enum, RepeatIntEnum, IntEnum::BAR}
146 test_primitive! {test_primitive_long_enum, RepeatLongEnum, LongEnum::FOO}
147
148 #[test]
test_repeat_string()149 fn test_repeat_string() {
150 let service = get_test_service();
151 let inputs = [
152 "typical string".into(),
153 String::new(),
154 "\0\0".into(),
155 // This is actually two unicode code points:
156 // U+10437: The 'small letter yee' character in the deseret alphabet
157 // U+20AC: A euro sign
158 String::from_utf16(&[0xD801, 0xDC37, 0x20AC]).expect("error converting string"),
159 ITestService::STRING_TEST_CONSTANT.into(),
160 ITestService::STRING_TEST_CONSTANT2.into(),
161 ];
162 for input in &inputs {
163 let result = service.RepeatString(&input);
164 assert_eq!(result.as_ref(), Ok(input));
165 }
166 }
167
168 macro_rules! test_reverse_array {
169 ($test:ident, $func:ident, $array:expr) => {
170 #[test]
171 fn $test() {
172 let mut array = $array;
173
174 // Java needs initial values here (can't resize arrays)
175 let mut repeated = vec![Default::default(); array.len()];
176
177 let result = get_test_service().$func(&array, &mut repeated);
178 assert_eq!(repeated, array);
179 array.reverse();
180 assert_eq!(result, Ok(array));
181 }
182 };
183 }
184
185 test_reverse_array! {test_array_boolean, ReverseBoolean, vec![true, false, false]}
186 test_reverse_array! {test_array_byte, ReverseByte, vec![255u8, 0u8, 127u8]}
187 test_reverse_array! {
188 service,
189 ReverseChar,
190 vec!['A' as u16, 'B' as u16, 'C' as u16]
191 }
192 test_reverse_array! {test_array_int, ReverseInt, vec![1, 2, 3]}
193 test_reverse_array! {test_array_long, ReverseLong, vec![-1i64, 0i64, 1i64 << 60]}
194 test_reverse_array! {test_array_float, ReverseFloat, vec![-0.3f32, -0.7f32, 8.0f32]}
195 test_reverse_array! {
196 test_array_double,
197 ReverseDouble,
198 vec![1.0f64 / 3.0f64, 1.0f64 / 7.0f64, 42.0f64]
199 }
200 test_reverse_array! {
201 test_array_string,
202 ReverseString,
203 vec!["f".into(), "a".into(), "b".into()]
204 }
205 test_reverse_array! {
206 test_array_byte_enum,
207 ReverseByteEnum,
208 vec![ByteEnum::FOO, ByteEnum::BAR, ByteEnum::BAR]
209 }
210 test_reverse_array! {
211 test_array_byte_enum_v2,
212 ReverseByteEnum,
213 vec![ByteEnum::FOO, ByteEnum::BAR, ByteEnum::BAZ]
214 }
215 test_reverse_array! {
216 test_array_int_enum,
217 ReverseIntEnum,
218 vec![IntEnum::FOO, IntEnum::BAR, IntEnum::BAR]
219 }
220 test_reverse_array! {
221 test_array_long_enum,
222 ReverseLongEnum,
223 vec![LongEnum::FOO, LongEnum::BAR, LongEnum::BAR]
224 }
225 test_reverse_array! {
226 test_array_string_list,
227 ReverseStringList,
228 vec!["f".into(), "a".into(), "b".into()]
229 }
230 test_reverse_array! {
231 test_array_utf8_string,
232 ReverseUtf8CppString,
233 vec![
234 "a".into(),
235 String::new(),
236 std::str::from_utf8(&[0xC3, 0xB8])
237 .expect("error converting string")
238 .into(),
239 ]
240 }
241
242 #[test]
test_binder_exchange()243 fn test_binder_exchange() {
244 const NAME: &str = "Smythe";
245 let service = get_test_service();
246 let got = service
247 .GetOtherTestService(NAME)
248 .expect("error calling GetOtherTestService");
249 assert_eq!(got.GetName().as_ref().map(String::as_ref), Ok(NAME));
250 assert_eq!(service.VerifyName(&got, NAME), Ok(true));
251 }
252
build_pipe() -> (File, File)253 fn build_pipe() -> (File, File) {
254 // Safety: we get two file descriptors from pipe()
255 // and pass them after checking if the function returned
256 // without an error, so the descriptors should be valid
257 // by that point
258 unsafe {
259 let mut fds = [0, 0];
260 if libc::pipe(fds.as_mut_ptr()) != 0 {
261 panic!("pipe() error");
262 }
263 (File::from_raw_fd(fds[0]), File::from_raw_fd(fds[1]))
264 }
265 }
266
267 #[test]
test_parcel_file_descriptor()268 fn test_parcel_file_descriptor() {
269 let service = get_test_service();
270 let (mut read_file, write_file) = build_pipe();
271
272 let write_pfd = binder::ParcelFileDescriptor::new(write_file);
273 let result_pfd = service
274 .RepeatParcelFileDescriptor(&write_pfd)
275 .expect("error calling RepeatParcelFileDescriptor");
276
277 const TEST_DATA: &[u8] = b"FrazzleSnazzleFlimFlamFlibbityGumboChops";
278 result_pfd
279 .as_ref()
280 .write_all(TEST_DATA)
281 .expect("error writing to pipe");
282
283 let mut buf = [0u8; TEST_DATA.len()];
284 read_file
285 .read_exact(&mut buf)
286 .expect("error reading from pipe");
287 assert_eq!(&buf[..], TEST_DATA);
288 }
289
290 #[test]
test_parcel_file_descriptor_array()291 fn test_parcel_file_descriptor_array() {
292 let service = get_test_service();
293
294 let (read_file, write_file) = build_pipe();
295 let input = vec![
296 binder::ParcelFileDescriptor::new(read_file),
297 binder::ParcelFileDescriptor::new(write_file),
298 ];
299
300 let mut repeated = vec![];
301
302 let backend = service.getBackendType().expect("error getting backend type");
303 if backend == BackendType::JAVA {
304 // Java needs initial values here (can't resize arrays)
305 // Other backends can't accept 'None', but we can use it in Java for convenience, rather
306 // than creating file descriptors.
307 repeated = vec![None, None];
308 }
309
310 let result = service
311 .ReverseParcelFileDescriptorArray(&input[..], &mut repeated)
312 .expect("error calling ReverseParcelFileDescriptorArray");
313
314 input[1]
315 .as_ref()
316 .write_all(b"First")
317 .expect("error writing to pipe");
318 repeated[1]
319 .as_mut()
320 .expect("received None for ParcelFileDescriptor")
321 .as_ref()
322 .write_all(b"Second")
323 .expect("error writing to pipe");
324 result[0]
325 .as_ref()
326 .write_all(b"Third")
327 .expect("error writing to pipe");
328
329 const TEST_DATA: &[u8] = b"FirstSecondThird";
330 let mut buf = [0u8; TEST_DATA.len()];
331 input[0]
332 .as_ref()
333 .read_exact(&mut buf)
334 .expect("error reading from pipe");
335 assert_eq!(&buf[..], TEST_DATA);
336 }
337
338 #[test]
test_service_specific_exception()339 fn test_service_specific_exception() {
340 let service = get_test_service();
341
342 let backend = service.getBackendType().expect("error getting backend type");
343 if backend == BackendType::JAVA {
344 // TODO(b/178861468): not correctly thrown from Java
345 return;
346 }
347
348 for i in -1..2 {
349 let result = service.ThrowServiceException(i);
350 assert!(result.is_err());
351
352 let status = result.unwrap_err();
353 assert_eq!(
354 status.exception_code(),
355 binder::ExceptionCode::SERVICE_SPECIFIC
356 );
357 assert_eq!(status.service_specific_error(), i);
358 }
359 }
360
361 macro_rules! test_nullable {
362 ($test:ident, $func:ident, $value:expr) => {
363 #[test]
364 fn $test() {
365 let service = get_test_service();
366 let value = Some($value);
367 let result = service.$func(value.as_deref());
368 assert_eq!(result, Ok(value));
369
370 let result = service.$func(None);
371 assert_eq!(result, Ok(None));
372 }
373 };
374 }
375
376 test_nullable! {test_nullable_array_int, RepeatNullableIntArray, vec![1, 2, 3]}
377 test_nullable! {
378 test_nullable_array_byte_enum,
379 RepeatNullableByteEnumArray,
380 vec![ByteEnum::FOO, ByteEnum::BAR]
381 }
382 test_nullable! {
383 test_nullable_array_int_enum,
384 RepeatNullableIntEnumArray,
385 vec![IntEnum::FOO, IntEnum::BAR]
386 }
387 test_nullable! {
388 test_nullable_array_long_enum,
389 RepeatNullableLongEnumArray,
390 vec![LongEnum::FOO, LongEnum::BAR]
391 }
392 test_nullable! {test_nullable_string, RepeatNullableString, "Blooob".into()}
393 test_nullable! {
394 test_nullable_string_list,
395 RepeatNullableStringList,
396 vec![
397 Some("Wat".into()),
398 Some("Blooob".into()),
399 Some("Wat".into()),
400 None,
401 Some("YEAH".into()),
402 Some("OKAAAAY".into()),
403 ]
404 }
405
406 #[test]
test_nullable_parcelable()407 fn test_nullable_parcelable() {
408 let value = StructuredParcelable::StructuredParcelable{
409 f: 42,
410 ..Default::default()
411 };
412
413 let service = get_test_service();
414 let value = Some(value);
415 let result = service.RepeatNullableParcelable(value.as_ref());
416 assert_eq!(result, Ok(value));
417
418 let result = service.RepeatNullableParcelable(None);
419 assert_eq!(result, Ok(None));
420 }
421
422 #[test]
test_binder()423 fn test_binder() {
424 let service = get_test_service();
425 assert!(service
426 .GetCallback(true)
427 .expect("error calling GetCallback")
428 .is_none());
429 let callback = service
430 .GetCallback(false)
431 .expect("error calling GetCallback")
432 .expect("expected Some from GetCallback");
433
434 // We don't have any place to get a fresh `SpIBinder`, so we
435 // reuse the interface for the binder tests
436 let binder = callback.as_binder();
437 assert_eq!(service.TakesAnIBinder(&binder), Ok(()));
438 assert_eq!(service.TakesANullableIBinder(None), Ok(()));
439 assert_eq!(service.TakesANullableIBinder(Some(&binder)), Ok(()));
440 }
441
442 macro_rules! test_reverse_null_array {
443 ($service:expr, $func:ident, $expect_repeated:expr) => {{
444 let mut repeated = None;
445 let result = $service.$func(None, &mut repeated);
446 assert_eq!(repeated, $expect_repeated);
447 assert_eq!(result, Ok(None));
448 }};
449 }
450
451 macro_rules! test_reverse_nullable_array {
452 ($service:expr, $func:ident, $array:expr) => {{
453 let mut array = $array;
454 // Java needs initial values here (can't resize arrays)
455 let mut repeated = Some(vec![Default::default(); array.len()]);
456 let result = $service.$func(Some(&array[..]), &mut repeated);
457 assert_eq!(repeated.as_ref(), Some(&array));
458 array.reverse();
459 assert_eq!(result, Ok(Some(array)));
460 }};
461 }
462
463 #[test]
test_utf8_string()464 fn test_utf8_string() {
465 let service = get_test_service();
466 let inputs = [
467 "typical string",
468 "",
469 "\0\0",
470 std::str::from_utf8(&[0xF0, 0x90, 0x90, 0xB7, 0xE2, 0x82, 0xAC])
471 .expect("error converting string"),
472 ITestService::STRING_TEST_CONSTANT_UTF8,
473 ];
474 for input in &inputs {
475 let result = service.RepeatUtf8CppString(input);
476 assert_eq!(result.as_ref().map(String::as_str), Ok(*input));
477
478 let result = service.RepeatNullableUtf8CppString(Some(input));
479 assert_eq!(result.as_ref().map(Option::as_deref), Ok(Some(*input)));
480 }
481
482 let result = service.RepeatNullableUtf8CppString(None);
483 assert_eq!(result, Ok(None));
484
485 let inputs = vec![
486 Some("typical string".into()),
487 Some(String::new()),
488 None,
489 Some(
490 std::str::from_utf8(&[0xF0, 0x90, 0x90, 0xB7, 0xE2, 0x82, 0xAC])
491 .expect("error converting string")
492 .into(),
493 ),
494 Some(ITestService::STRING_TEST_CONSTANT_UTF8.into()),
495 ];
496
497 // Java can't return a null list as a parameter
498 let backend = service.getBackendType().expect("error getting backend type");
499 let null_output = if backend == BackendType::JAVA { Some(vec![]) } else { None };
500 test_reverse_null_array!(service, ReverseUtf8CppStringList, null_output);
501
502 test_reverse_null_array!(service, ReverseNullableUtf8CppString, None);
503
504 test_reverse_nullable_array!(service, ReverseUtf8CppStringList, inputs.clone());
505 test_reverse_nullable_array!(service, ReverseNullableUtf8CppString, inputs);
506 }
507
508 #[allow(clippy::approx_constant)]
509 #[allow(clippy::float_cmp)]
510 #[test]
test_parcelable()511 fn test_parcelable() {
512 let service = get_test_service();
513 let mut parcelable = StructuredParcelable::StructuredParcelable::default();
514
515 const DESIRED_VALUE: i32 = 23;
516 parcelable.f = DESIRED_VALUE;
517
518 assert_eq!(parcelable.stringDefaultsToFoo, "foo");
519 assert_eq!(parcelable.byteDefaultsToFour, 4);
520 assert_eq!(parcelable.intDefaultsToFive, 5);
521 assert_eq!(parcelable.longDefaultsToNegativeSeven, -7);
522 assert_eq!(parcelable.booleanDefaultsToTrue, true);
523 assert_eq!(parcelable.charDefaultsToC, 'C' as u16);
524 assert_eq!(parcelable.floatDefaultsToPi, 3.14f32);
525 assert_eq!(parcelable.doubleWithDefault, -3.14e17f64);
526 assert_eq!(parcelable.boolDefault, false);
527 assert_eq!(parcelable.byteDefault, 0);
528 assert_eq!(parcelable.intDefault, 0);
529 assert_eq!(parcelable.longDefault, 0);
530 assert_eq!(parcelable.floatDefault, 0.0f32);
531 assert_eq!(parcelable.doubleDefault, 0.0f64);
532 assert_eq!(parcelable.arrayDefaultsTo123, &[1, 2, 3]);
533 assert!(parcelable.arrayDefaultsToEmpty.is_empty());
534
535 let result = service.FillOutStructuredParcelable(&mut parcelable);
536 assert_eq!(result, Ok(()));
537
538 assert_eq!(
539 parcelable.shouldContainThreeFs,
540 [DESIRED_VALUE, DESIRED_VALUE, DESIRED_VALUE]
541 );
542 assert_eq!(parcelable.shouldBeJerry, "Jerry");
543 assert_eq!(parcelable.int32_min, i32::MIN);
544 assert_eq!(parcelable.int32_max, i32::MAX);
545 assert_eq!(parcelable.int64_max, i64::MAX);
546 assert_eq!(parcelable.hexInt32_neg_1, -1);
547 for i in parcelable.int32_1 {
548 assert_eq!(i, 1);
549 }
550 for i in parcelable.int64_1 {
551 assert_eq!(i, 1);
552 }
553 assert_eq!(parcelable.hexInt32_pos_1, 1);
554 assert_eq!(parcelable.hexInt64_pos_1, 1);
555 assert_eq!(parcelable.const_exprs_1.0, 1);
556 assert_eq!(parcelable.const_exprs_2.0, 1);
557 assert_eq!(parcelable.const_exprs_3.0, 1);
558 assert_eq!(parcelable.const_exprs_4.0, 1);
559 assert_eq!(parcelable.const_exprs_5.0, 1);
560 assert_eq!(parcelable.const_exprs_6.0, 1);
561 assert_eq!(parcelable.const_exprs_7.0, 1);
562 assert_eq!(parcelable.const_exprs_8.0, 1);
563 assert_eq!(parcelable.const_exprs_9.0, 1);
564 assert_eq!(parcelable.const_exprs_10.0, 1);
565 assert_eq!(parcelable.addString1, "hello world!");
566 assert_eq!(
567 parcelable.addString2,
568 "The quick brown fox jumps over the lazy dog."
569 );
570
571 assert_eq!(parcelable.shouldSetBit0AndBit2, StructuredParcelable::BIT0 | StructuredParcelable::BIT2);
572
573 assert_eq!(parcelable.u, Some(Union::Union::Ns(vec![1, 2, 3])));
574 assert_eq!(parcelable.shouldBeConstS1, Some(Union::Union::S(Union::S1.to_string())))
575 }
576
577 #[test]
test_unions()578 fn test_unions() {
579 assert_eq!(Union::Union::default(), Union::Union::Ns(vec![]));
580 assert_eq!(EnumUnion::default(), EnumUnion::IntEnum(IntEnum::FOO));
581 }
582
583 const EXPECTED_ARG_VALUE: i32 = 100;
584 const EXPECTED_RETURN_VALUE: i32 = 200;
585
586 struct TestDefaultImpl;
587
588 impl binder::Interface for TestDefaultImpl {}
589
590 impl ITestServiceDefault for TestDefaultImpl {
UnimplementedMethod(&self, arg: i32) -> binder::Result<i32>591 fn UnimplementedMethod(&self, arg: i32) -> binder::Result<i32> {
592 assert_eq!(arg, EXPECTED_ARG_VALUE);
593 Ok(EXPECTED_RETURN_VALUE)
594 }
595 }
596
597 #[test]
test_default_impl()598 fn test_default_impl() {
599 let service = get_test_service();
600 let di: ITestServiceDefaultRef = Some(Arc::new(TestDefaultImpl));
601 <BpTestService as ITestService::ITestService>::setDefaultImpl(di);
602
603 let result = service.UnimplementedMethod(EXPECTED_ARG_VALUE);
604 assert_eq!(result, Ok(EXPECTED_RETURN_VALUE));
605 }
606
607 #[test]
test_versioned_interface_version()608 fn test_versioned_interface_version() {
609 let service: binder::Strong<dyn IFooInterface::IFooInterface> =
610 binder::get_interface(<BpFooInterface as IFooInterface::IFooInterface>::get_descriptor())
611 .expect("did not get binder service");
612
613 let version = service.getInterfaceVersion();
614 assert_eq!(version, Ok(1));
615 }
616
617 #[test]
test_versioned_interface_hash()618 fn test_versioned_interface_hash() {
619 let service: binder::Strong<dyn IFooInterface::IFooInterface> =
620 binder::get_interface(<BpFooInterface as IFooInterface::IFooInterface>::get_descriptor())
621 .expect("did not get binder service");
622
623 let hash = service.getInterfaceHash();
624 assert_eq!(
625 hash.as_ref().map(String::as_str),
626 Ok("9e7be1859820c59d9d55dd133e71a3687b5d2e5b")
627 );
628 }
629
630 #[test]
test_versioned_known_union_field_is_ok()631 fn test_versioned_known_union_field_is_ok() {
632 let service: binder::Strong<dyn IFooInterface::IFooInterface> =
633 binder::get_interface(<BpFooInterface as IFooInterface::IFooInterface>::get_descriptor())
634 .expect("did not get binder service");
635
636 assert_eq!(service.acceptUnionAndReturnString(&BazUnion::IntNum(42)), Ok(String::from("42")));
637 }
638
639 #[test]
test_versioned_unknown_union_field_triggers_error()640 fn test_versioned_unknown_union_field_triggers_error() {
641 let service: binder::Strong<dyn IFooInterface::IFooInterface> =
642 binder::get_interface(<BpFooInterface as IFooInterface::IFooInterface>::get_descriptor())
643 .expect("did not get binder service");
644
645 let ret = service.acceptUnionAndReturnString(&BazUnion::LongNum(42));
646 assert!(!ret.is_ok());
647
648 let main_service = get_test_service();
649 let backend = main_service.getBackendType().expect("error getting backend type");
650
651 // b/173458620 - for investigation of fixing difference
652 if backend == BackendType::JAVA {
653 assert_eq!(ret.unwrap_err().exception_code(), binder::ExceptionCode::ILLEGAL_ARGUMENT);
654 } else {
655 assert_eq!(ret.unwrap_err().transaction_error(), binder::StatusCode::BAD_VALUE);
656 }
657 }
658
659 #[test]
test_array_of_parcelable_with_new_field()660 fn test_array_of_parcelable_with_new_field() {
661 let service: binder::Strong<dyn IFooInterface::IFooInterface> =
662 binder::get_interface(<BpFooInterface as IFooInterface::IFooInterface>::get_descriptor())
663 .expect("did not get binder service");
664
665 let foos = [Default::default(), Default::default(), Default::default()];
666 let ret = service.returnsLengthOfFooArray(&foos);
667 assert_eq!(ret, Ok(foos.len() as i32));
668 }
669
670 #[test]
test_read_data_correctly_after_parcelable_with_new_field()671 fn test_read_data_correctly_after_parcelable_with_new_field() {
672 let service: binder::Strong<dyn IFooInterface::IFooInterface> =
673 binder::get_interface(<BpFooInterface as IFooInterface::IFooInterface>::get_descriptor())
674 .expect("did not get binder service");
675
676 let in_foo = Default::default();
677 let mut inout_foo = Default::default();
678 let mut out_foo = Default::default();
679 let ret = service.ignoreParcelablesAndRepeatInt(&in_foo, &mut inout_foo, &mut out_foo, 43);
680 assert_eq!(ret, Ok(43));
681 }
682
test_renamed_interface<F>(f: F) where F: FnOnce(binder::Strong<dyn IOldName::IOldName>, binder::Strong<dyn INewName::INewName>),683 fn test_renamed_interface<F>(f: F)
684 where
685 F: FnOnce(binder::Strong<dyn IOldName::IOldName>, binder::Strong<dyn INewName::INewName>),
686 {
687 let service = get_test_service();
688 let old_name = service.GetOldNameInterface();
689 assert!(old_name.is_ok());
690
691 let new_name = service.GetNewNameInterface();
692 assert!(new_name.is_ok());
693
694 f(old_name.unwrap(), new_name.unwrap());
695 }
696
697 #[test]
test_renamed_interface_old_as_old()698 fn test_renamed_interface_old_as_old() {
699 test_renamed_interface(|old_name, _| {
700 assert_eq!(
701 <BpOldName as IOldName::IOldName>::get_descriptor(),
702 "android.aidl.tests.IOldName"
703 );
704
705 let real_name = old_name.RealName();
706 assert_eq!(real_name.as_ref().map(String::as_str), Ok("OldName"));
707 });
708 }
709
710 #[test]
test_renamed_interface_new_as_new()711 fn test_renamed_interface_new_as_new() {
712 test_renamed_interface(|_, new_name| {
713 assert_eq!(
714 <BpNewName as INewName::INewName>::get_descriptor(),
715 "android.aidl.tests.IOldName"
716 );
717
718 let real_name = new_name.RealName();
719 assert_eq!(real_name.as_ref().map(String::as_str), Ok("NewName"));
720 });
721 }
722
723 #[test]
test_renamed_interface_old_as_new()724 fn test_renamed_interface_old_as_new() {
725 test_renamed_interface(|old_name, _| {
726 let new_name = old_name
727 .as_binder()
728 .into_interface::<dyn INewName::INewName>();
729 assert!(new_name.is_ok());
730
731 let real_name = new_name.unwrap().RealName();
732 assert_eq!(real_name.as_ref().map(String::as_str), Ok("OldName"));
733 });
734 }
735
736 #[test]
test_renamed_interface_new_as_old()737 fn test_renamed_interface_new_as_old() {
738 test_renamed_interface(|_, new_name| {
739 let old_name = new_name
740 .as_binder()
741 .into_interface::<dyn IOldName::IOldName>();
742 assert!(old_name.is_ok());
743
744 let real_name = old_name.unwrap().RealName();
745 assert_eq!(real_name.as_ref().map(String::as_str), Ok("NewName"));
746 });
747 }
748