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 service for the AIDL compiler.
18 
19 use aidl_test_interface::aidl::android::aidl::tests::ITestService::{
20     self, BnTestService, BpTestService,
21 };
22 use aidl_test_interface::aidl::android::aidl::tests::{
23     BackendType::BackendType, ByteEnum::ByteEnum, ConstantExpressionEnum::ConstantExpressionEnum,
24     INamedCallback, INewName, IOldName, IntEnum::IntEnum, LongEnum::LongEnum, StructuredParcelable,
25     Union,
26 };
27 use aidl_test_interface::binder::{
28     self, BinderFeatures, Interface, ParcelFileDescriptor, SpIBinder,
29 };
30 use aidl_test_versioned_interface::aidl::android::aidl::versioned::tests::{
31     BazUnion::BazUnion, Foo::Foo, IFooInterface, IFooInterface::BnFooInterface,
32     IFooInterface::BpFooInterface,
33 };
34 use std::collections::HashMap;
35 use std::sync::Mutex;
36 
dup_fd(fd: &ParcelFileDescriptor) -> ParcelFileDescriptor37 fn dup_fd(fd: &ParcelFileDescriptor) -> ParcelFileDescriptor {
38     ParcelFileDescriptor::new(fd.as_ref().try_clone().unwrap())
39 }
40 
41 struct NamedCallback(String);
42 
43 impl Interface for NamedCallback {}
44 
45 impl INamedCallback::INamedCallback for NamedCallback {
GetName(&self) -> binder::Result<String>46     fn GetName(&self) -> binder::Result<String> {
47         Ok(self.0.clone())
48     }
49 }
50 
51 struct OldName;
52 
53 impl Interface for OldName {}
54 
55 impl IOldName::IOldName for OldName {
RealName(&self) -> binder::Result<String>56     fn RealName(&self) -> binder::Result<String> {
57         Ok("OldName".into())
58     }
59 }
60 
61 #[derive(Debug, Default)]
62 struct NewName;
63 
64 impl Interface for NewName {}
65 
66 impl INewName::INewName for NewName {
RealName(&self) -> binder::Result<String>67     fn RealName(&self) -> binder::Result<String> {
68         Ok("NewName".into())
69     }
70 }
71 
72 #[derive(Default)]
73 struct TestService {
74     service_map: Mutex<HashMap<String, binder::Strong<dyn INamedCallback::INamedCallback>>>,
75 }
76 
77 impl Interface for TestService {}
78 
79 macro_rules! impl_repeat {
80     ($repeat_name:ident, $type:ty) => {
81         fn $repeat_name(&self, token: $type) -> binder::Result<$type> {
82             Ok(token)
83         }
84     };
85 }
86 
87 macro_rules! impl_reverse {
88     ($reverse_name:ident, $type:ty) => {
89         fn $reverse_name(
90             &self,
91             input: &[$type],
92             repeated: &mut Vec<$type>,
93         ) -> binder::Result<Vec<$type>> {
94             repeated.clear();
95             repeated.extend_from_slice(input);
96             Ok(input.iter().rev().cloned().collect())
97         }
98     };
99 }
100 
101 macro_rules! impl_repeat_reverse {
102     ($repeat_name:ident, $reverse_name:ident, $type:ty) => {
103         impl_repeat! {$repeat_name, $type}
104         impl_reverse! {$reverse_name, $type}
105     };
106 }
107 
108 macro_rules! impl_repeat_nullable {
109     ($repeat_nullable_name:ident, $type:ty) => {
110         fn $repeat_nullable_name(
111             &self,
112             input: Option<&[$type]>,
113         ) -> binder::Result<Option<Vec<$type>>> {
114             Ok(input.map(<[$type]>::to_vec))
115         }
116     };
117 }
118 
119 impl ITestService::ITestService for TestService {
120     impl_repeat! {RepeatByte, i8}
121     impl_reverse! {ReverseByte, u8}
122 
UnimplementedMethod(&self, _: i32) -> binder::Result<i32>123     fn UnimplementedMethod(&self, _: i32) -> binder::Result<i32> {
124         // Pretend this method hasn't been implemented
125         Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
126     }
127 
TestOneway(&self) -> binder::Result<()>128     fn TestOneway(&self) -> binder::Result<()> {
129         Err(binder::StatusCode::UNKNOWN_ERROR.into())
130     }
131 
Deprecated(&self) -> binder::Result<()>132     fn Deprecated(&self) -> binder::Result<()> {
133         Ok(())
134     }
135 
136     impl_repeat_reverse! {RepeatBoolean, ReverseBoolean, bool}
137     impl_repeat_reverse! {RepeatChar, ReverseChar, u16}
138     impl_repeat_reverse! {RepeatInt, ReverseInt, i32}
139     impl_repeat_reverse! {RepeatLong, ReverseLong, i64}
140     impl_repeat_reverse! {RepeatFloat, ReverseFloat, f32}
141     impl_repeat_reverse! {RepeatDouble, ReverseDouble, f64}
142     impl_repeat_reverse! {RepeatByteEnum, ReverseByteEnum, ByteEnum}
143     impl_repeat_reverse! {RepeatIntEnum, ReverseIntEnum, IntEnum}
144     impl_repeat_reverse! {RepeatLongEnum, ReverseLongEnum, LongEnum}
145     impl_reverse! {ReverseString, String}
146     impl_reverse! {ReverseStringList, String}
147     impl_reverse! {ReverseUtf8CppString, String}
148 
RepeatString(&self, input: &str) -> binder::Result<String>149     fn RepeatString(&self, input: &str) -> binder::Result<String> {
150         Ok(input.into())
151     }
152 
RepeatUtf8CppString(&self, input: &str) -> binder::Result<String>153     fn RepeatUtf8CppString(&self, input: &str) -> binder::Result<String> {
154         Ok(input.into())
155     }
156 
GetOtherTestService( &self, name: &str, ) -> binder::Result<binder::Strong<dyn INamedCallback::INamedCallback>>157     fn GetOtherTestService(
158         &self,
159         name: &str,
160     ) -> binder::Result<binder::Strong<dyn INamedCallback::INamedCallback>> {
161         let mut service_map = self.service_map.lock().unwrap();
162         let other_service = service_map.entry(name.into()).or_insert_with(|| {
163             let named_callback = NamedCallback(name.into());
164             INamedCallback::BnNamedCallback::new_binder(named_callback, BinderFeatures::default())
165         });
166         Ok(other_service.to_owned())
167     }
168 
VerifyName( &self, service: &binder::Strong<dyn INamedCallback::INamedCallback>, name: &str, ) -> binder::Result<bool>169     fn VerifyName(
170         &self,
171         service: &binder::Strong<dyn INamedCallback::INamedCallback>,
172         name: &str,
173     ) -> binder::Result<bool> {
174         service.GetName().map(|found_name| found_name == name)
175     }
176 
RepeatParcelFileDescriptor( &self, read: &ParcelFileDescriptor, ) -> binder::Result<ParcelFileDescriptor>177     fn RepeatParcelFileDescriptor(
178         &self,
179         read: &ParcelFileDescriptor,
180     ) -> binder::Result<ParcelFileDescriptor> {
181         Ok(dup_fd(read))
182     }
183 
ReverseParcelFileDescriptorArray( &self, input: &[ParcelFileDescriptor], repeated: &mut Vec<Option<ParcelFileDescriptor>>, ) -> binder::Result<Vec<ParcelFileDescriptor>>184     fn ReverseParcelFileDescriptorArray(
185         &self,
186         input: &[ParcelFileDescriptor],
187         repeated: &mut Vec<Option<ParcelFileDescriptor>>,
188     ) -> binder::Result<Vec<ParcelFileDescriptor>> {
189         repeated.clear();
190         repeated.extend(input.iter().map(dup_fd).map(Some));
191         Ok(input.iter().rev().map(dup_fd).collect())
192     }
193 
ThrowServiceException(&self, code: i32) -> binder::Result<()>194     fn ThrowServiceException(&self, code: i32) -> binder::Result<()> {
195         Err(binder::Status::new_service_specific_error(code, None))
196     }
197 
198     impl_repeat_nullable! {RepeatNullableIntArray, i32}
199     impl_repeat_nullable! {RepeatNullableByteEnumArray, ByteEnum}
200     impl_repeat_nullable! {RepeatNullableIntEnumArray, IntEnum}
201     impl_repeat_nullable! {RepeatNullableLongEnumArray, LongEnum}
202     impl_repeat_nullable! {RepeatNullableStringList, Option<String>}
203 
RepeatNullableString(&self, input: Option<&str>) -> binder::Result<Option<String>>204     fn RepeatNullableString(&self, input: Option<&str>) -> binder::Result<Option<String>> {
205         Ok(input.map(String::from))
206     }
207 
RepeatNullableUtf8CppString(&self, input: Option<&str>) -> binder::Result<Option<String>>208     fn RepeatNullableUtf8CppString(&self, input: Option<&str>) -> binder::Result<Option<String>> {
209         Ok(input.map(String::from))
210     }
211 
RepeatNullableParcelable( &self, input: Option<&StructuredParcelable::StructuredParcelable>, ) -> binder::Result<Option<StructuredParcelable::StructuredParcelable>>212     fn RepeatNullableParcelable(
213         &self,
214         input: Option<&StructuredParcelable::StructuredParcelable>,
215     ) -> binder::Result<Option<StructuredParcelable::StructuredParcelable>> {
216         Ok(input.cloned())
217     }
218 
TakesAnIBinder(&self, _: &SpIBinder) -> binder::Result<()>219     fn TakesAnIBinder(&self, _: &SpIBinder) -> binder::Result<()> {
220         Ok(())
221     }
222 
TakesANullableIBinder(&self, _: Option<&SpIBinder>) -> binder::Result<()>223     fn TakesANullableIBinder(&self, _: Option<&SpIBinder>) -> binder::Result<()> {
224         Ok(())
225     }
226 
ReverseNullableUtf8CppString( &self, input: Option<&[Option<String>]>, repeated: &mut Option<Vec<Option<String>>>, ) -> binder::Result<Option<Vec<Option<String>>>>227     fn ReverseNullableUtf8CppString(
228         &self,
229         input: Option<&[Option<String>]>,
230         repeated: &mut Option<Vec<Option<String>>>,
231     ) -> binder::Result<Option<Vec<Option<String>>>> {
232         if let Some(input) = input {
233             *repeated = Some(input.to_vec());
234             Ok(Some(input.iter().rev().cloned().collect()))
235         } else {
236             // We don't touch `repeated` here, since
237             // the C++ test service doesn't either
238             Ok(None)
239         }
240     }
241 
ReverseUtf8CppStringList( &self, input: Option<&[Option<String>]>, repeated: &mut Option<Vec<Option<String>>>, ) -> binder::Result<Option<Vec<Option<String>>>>242     fn ReverseUtf8CppStringList(
243         &self,
244         input: Option<&[Option<String>]>,
245         repeated: &mut Option<Vec<Option<String>>>,
246     ) -> binder::Result<Option<Vec<Option<String>>>> {
247         self.ReverseNullableUtf8CppString(input, repeated)
248     }
249 
GetCallback( &self, return_null: bool, ) -> binder::Result<Option<binder::Strong<dyn INamedCallback::INamedCallback>>>250     fn GetCallback(
251         &self,
252         return_null: bool,
253     ) -> binder::Result<Option<binder::Strong<dyn INamedCallback::INamedCallback>>> {
254         if return_null {
255             Ok(None)
256         } else {
257             self.GetOtherTestService("ABT: always be testing").map(Some)
258         }
259     }
260 
FillOutStructuredParcelable( &self, parcelable: &mut StructuredParcelable::StructuredParcelable, ) -> binder::Result<()>261     fn FillOutStructuredParcelable(
262         &self,
263         parcelable: &mut StructuredParcelable::StructuredParcelable,
264     ) -> binder::Result<()> {
265         parcelable.shouldBeJerry = "Jerry".into();
266         parcelable.shouldContainThreeFs = vec![parcelable.f, parcelable.f, parcelable.f];
267         parcelable.shouldBeByteBar = ByteEnum::BAR;
268         parcelable.shouldBeIntBar = IntEnum::BAR;
269         parcelable.shouldBeLongBar = LongEnum::BAR;
270         parcelable.shouldContainTwoByteFoos = vec![ByteEnum::FOO, ByteEnum::FOO];
271         parcelable.shouldContainTwoIntFoos = vec![IntEnum::FOO, IntEnum::FOO];
272         parcelable.shouldContainTwoLongFoos = vec![LongEnum::FOO, LongEnum::FOO];
273 
274         parcelable.const_exprs_1 = ConstantExpressionEnum::decInt32_1;
275         parcelable.const_exprs_2 = ConstantExpressionEnum::decInt32_2;
276         parcelable.const_exprs_3 = ConstantExpressionEnum::decInt64_1;
277         parcelable.const_exprs_4 = ConstantExpressionEnum::decInt64_2;
278         parcelable.const_exprs_5 = ConstantExpressionEnum::decInt64_3;
279         parcelable.const_exprs_6 = ConstantExpressionEnum::decInt64_4;
280         parcelable.const_exprs_7 = ConstantExpressionEnum::hexInt32_1;
281         parcelable.const_exprs_8 = ConstantExpressionEnum::hexInt32_2;
282         parcelable.const_exprs_9 = ConstantExpressionEnum::hexInt32_3;
283         parcelable.const_exprs_10 = ConstantExpressionEnum::hexInt64_1;
284 
285         parcelable.shouldSetBit0AndBit2 = StructuredParcelable::BIT0 | StructuredParcelable::BIT2;
286 
287         parcelable.u = Some(Union::Union::Ns(vec![1, 2, 3]));
288         parcelable.shouldBeConstS1 = Some(Union::Union::S(Union::S1.to_string()));
289         Ok(())
290     }
291 
GetOldNameInterface(&self) -> binder::Result<binder::Strong<dyn IOldName::IOldName>>292     fn GetOldNameInterface(&self) -> binder::Result<binder::Strong<dyn IOldName::IOldName>> {
293         Ok(IOldName::BnOldName::new_binder(
294             OldName,
295             BinderFeatures::default(),
296         ))
297     }
298 
GetNewNameInterface(&self) -> binder::Result<binder::Strong<dyn INewName::INewName>>299     fn GetNewNameInterface(&self) -> binder::Result<binder::Strong<dyn INewName::INewName>> {
300         Ok(INewName::BnNewName::new_binder(
301             NewName,
302             BinderFeatures::default(),
303         ))
304     }
305 
GetCppJavaTests(&self) -> binder::Result<Option<SpIBinder>>306     fn GetCppJavaTests(&self) -> binder::Result<Option<SpIBinder>> {
307         Ok(None)
308     }
309 
getBackendType(&self) -> binder::Result<BackendType>310     fn getBackendType(&self) -> binder::Result<BackendType> {
311         Ok(BackendType::RUST)
312     }
313 }
314 
315 struct FooInterface;
316 
317 impl Interface for FooInterface {}
318 
319 impl IFooInterface::IFooInterface for FooInterface {
originalApi(&self) -> binder::Result<()>320     fn originalApi(&self) -> binder::Result<()> {
321         Ok(())
322     }
acceptUnionAndReturnString(&self, u: &BazUnion) -> binder::Result<String>323     fn acceptUnionAndReturnString(&self, u: &BazUnion) -> binder::Result<String> {
324         match u {
325             BazUnion::IntNum(n) => Ok(n.to_string()),
326         }
327     }
returnsLengthOfFooArray(&self, foos: &[Foo]) -> binder::Result<i32>328     fn returnsLengthOfFooArray(&self, foos: &[Foo]) -> binder::Result<i32> {
329         Ok(foos.len() as i32)
330     }
ignoreParcelablesAndRepeatInt(&self, _in_foo: &Foo, _inout_foo: &mut Foo, _out_foo: &mut Foo, value: i32) -> binder::Result<i32>331     fn ignoreParcelablesAndRepeatInt(&self, _in_foo: &Foo, _inout_foo: &mut Foo, _out_foo: &mut Foo, value: i32) -> binder::Result<i32> {
332         Ok(value)
333     }
334 }
335 
main()336 fn main() {
337     binder::ProcessState::set_thread_pool_max_thread_count(0);
338     binder::ProcessState::start_thread_pool();
339 
340     let service_name = <BpTestService as ITestService::ITestService>::get_descriptor();
341     let service = BnTestService::new_binder(TestService::default(), BinderFeatures::default());
342     binder::add_service(service_name, service.as_binder()).expect("Could not register service");
343 
344     let versioned_service_name = <BpFooInterface as IFooInterface::IFooInterface>::get_descriptor();
345     let versioned_service = BnFooInterface::new_binder(FooInterface, BinderFeatures::default());
346     binder::add_service(versioned_service_name, versioned_service.as_binder())
347         .expect("Could not register service");
348 
349     binder::ProcessState::join_thread_pool();
350 }
351