1 /*
2 * Copyright 2024 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 //! A VM payload that exists to allow testing of the Rust wrapper for the VM payload APIs.
18
19 use anyhow::Result;
20 use com_android_microdroid_testservice::{
21 aidl::com::android::microdroid::testservice::{
22 IAppCallback::IAppCallback,
23 ITestService::{BnTestService, ITestService, PORT},
24 },
25 binder::{BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Status, Strong},
26 };
27 use cstr::cstr;
28 use log::{error, info};
29 use std::panic;
30 use std::process::exit;
31 use std::string::String;
32 use std::vec::Vec;
33
34 vm_payload::main!(main);
35
36 // Entry point of the Service VM client.
main()37 fn main() {
38 android_logger::init_once(
39 android_logger::Config::default()
40 .with_tag("microdroid_testlib_rust")
41 .with_max_level(log::LevelFilter::Debug),
42 );
43 // Redirect panic messages to logcat.
44 panic::set_hook(Box::new(|panic_info| {
45 error!("{panic_info}");
46 }));
47 if let Err(e) = try_main() {
48 error!("failed with {:?}", e);
49 exit(1);
50 }
51 }
52
try_main() -> Result<()>53 fn try_main() -> Result<()> {
54 info!("Welcome to the Rust test binary");
55
56 vm_payload::run_single_vsock_service(TestService::new_binder(), PORT.try_into()?)
57 }
58
59 struct TestService {}
60
61 impl Interface for TestService {}
62
63 impl TestService {
new_binder() -> Strong<dyn ITestService>64 fn new_binder() -> Strong<dyn ITestService> {
65 BnTestService::new_binder(TestService {}, BinderFeatures::default())
66 }
67 }
68
69 impl ITestService for TestService {
quit(&self) -> BinderResult<()>70 fn quit(&self) -> BinderResult<()> {
71 exit(0)
72 }
73
addInteger(&self, a: i32, b: i32) -> BinderResult<i32>74 fn addInteger(&self, a: i32, b: i32) -> BinderResult<i32> {
75 a.checked_add(b).ok_or_else(|| Status::new_exception(ExceptionCode::ILLEGAL_ARGUMENT, None))
76 }
77
getApkContentsPath(&self) -> BinderResult<String>78 fn getApkContentsPath(&self) -> BinderResult<String> {
79 Ok(vm_payload::apk_contents_path().to_string_lossy().to_string())
80 }
81
getEncryptedStoragePath(&self) -> BinderResult<String>82 fn getEncryptedStoragePath(&self) -> BinderResult<String> {
83 Ok(vm_payload::encrypted_storage_path()
84 .map(|p| p.to_string_lossy().to_string())
85 .unwrap_or("".to_string()))
86 }
87
insecurelyExposeVmInstanceSecret(&self) -> BinderResult<Vec<u8>>88 fn insecurelyExposeVmInstanceSecret(&self) -> BinderResult<Vec<u8>> {
89 let mut secret = vec![0u8; 32];
90 vm_payload::get_vm_instance_secret(b"identifier", secret.as_mut_slice());
91 Ok(secret)
92 }
93
94 // Everything below here is unimplemented. Implementations may be added as needed.
95
readProperty(&self, _: &str) -> BinderResult<String>96 fn readProperty(&self, _: &str) -> BinderResult<String> {
97 unimplemented()
98 }
insecurelyExposeAttestationCdi(&self) -> BinderResult<Vec<u8>>99 fn insecurelyExposeAttestationCdi(&self) -> BinderResult<Vec<u8>> {
100 unimplemented()
101 }
getBcc(&self) -> BinderResult<Vec<u8>>102 fn getBcc(&self) -> BinderResult<Vec<u8>> {
103 unimplemented()
104 }
runEchoReverseServer(&self) -> BinderResult<()>105 fn runEchoReverseServer(&self) -> BinderResult<()> {
106 unimplemented()
107 }
getEffectiveCapabilities(&self) -> BinderResult<Vec<String>>108 fn getEffectiveCapabilities(&self) -> BinderResult<Vec<String>> {
109 unimplemented()
110 }
getUid(&self) -> BinderResult<i32>111 fn getUid(&self) -> BinderResult<i32> {
112 unimplemented()
113 }
writeToFile(&self, _: &str, _: &str) -> BinderResult<()>114 fn writeToFile(&self, _: &str, _: &str) -> BinderResult<()> {
115 unimplemented()
116 }
readFromFile(&self, _: &str) -> BinderResult<String>117 fn readFromFile(&self, _: &str) -> BinderResult<String> {
118 unimplemented()
119 }
getFilePermissions(&self, _: &str) -> BinderResult<i32>120 fn getFilePermissions(&self, _: &str) -> BinderResult<i32> {
121 unimplemented()
122 }
getMountFlags(&self, _: &str) -> BinderResult<i32>123 fn getMountFlags(&self, _: &str) -> BinderResult<i32> {
124 unimplemented()
125 }
getPageSize(&self) -> BinderResult<i32>126 fn getPageSize(&self) -> BinderResult<i32> {
127 unimplemented()
128 }
requestCallback(&self, _: &Strong<dyn IAppCallback + 'static>) -> BinderResult<()>129 fn requestCallback(&self, _: &Strong<dyn IAppCallback + 'static>) -> BinderResult<()> {
130 unimplemented()
131 }
readLineFromConsole(&self) -> BinderResult<String>132 fn readLineFromConsole(&self) -> BinderResult<String> {
133 unimplemented()
134 }
135 }
136
unimplemented<T>() -> BinderResult<T>137 fn unimplemented<T>() -> BinderResult<T> {
138 let message = cstr!("Got a call to an unimplemented ITestService method in testbinary.rs");
139 error!("{message:?}");
140 Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, Some(message)))
141 }
142