1 // Copyright 2021, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use android_hardware_security_dice::aidl::android::hardware::security::dice::IDiceDevice::IDiceDevice;
16 use anyhow::Result;
17 use binder::Strong;
18 use keystore2_vintf::get_aidl_instances;
19 use std::sync::Arc;
20
21 static DICE_DEVICE_SERVICE_NAME: &str = &"android.hardware.security.dice";
22 static DICE_DEVICE_INTERFACE_NAME: &str = &"IDiceDevice";
23
24 /// This function iterates through all announced IDiceDevice services and runs the given test
25 /// closure against connections to each of them. It also modifies the panic hook to indicate
26 /// on which instance the test failed in case the test closure panics.
with_connection<R, F>(test: F) where F: Fn(&Strong<dyn IDiceDevice>) -> Result<R>,27 pub fn with_connection<R, F>(test: F)
28 where
29 F: Fn(&Strong<dyn IDiceDevice>) -> Result<R>,
30 {
31 let instances = get_aidl_instances(DICE_DEVICE_SERVICE_NAME, 1, DICE_DEVICE_INTERFACE_NAME);
32 let panic_hook = Arc::new(std::panic::take_hook());
33 for i in instances.into_iter() {
34 let panic_hook_clone = panic_hook.clone();
35 let instance_clone = i.clone();
36 std::panic::set_hook(Box::new(move |v| {
37 println!("While testing instance: \"{}\"", instance_clone);
38 panic_hook_clone(v)
39 }));
40 let connection: Strong<dyn IDiceDevice> = binder::get_interface(&format!(
41 "{}.{}/{}",
42 DICE_DEVICE_SERVICE_NAME, DICE_DEVICE_INTERFACE_NAME, i
43 ))
44 .unwrap();
45 test(&connection).unwrap();
46 drop(std::panic::take_hook());
47 }
48 // Cannot call unwrap here because the panic hook is not Debug.
49 std::panic::set_hook(match Arc::try_unwrap(panic_hook) {
50 Ok(hook) => hook,
51 _ => panic!("Failed to unwrap and reset previous panic hook."),
52 })
53 }
54