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