1 /*
2 * Copyright (C) 2023 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 FFI wrapper for APEX support library
18
19 mod apexinfo;
20
21 use apexinfo::{AApexInfo, AApexInfoError};
22 use std::ffi::c_char;
23
24 /// NOTE: Keep these constants in sync with apexsupport.h
25 const AAPEXINFO_OK: i32 = 0;
26 const AAPEXINFO_NO_APEX: i32 = 1;
27 const AAPEXINFO_ERROR_GET_EXECUTABLE_PATH: i32 = 2;
28 const AAPEXINFO_INALID_APEX: i32 = 3;
29
as_error_code(err: &AApexInfoError) -> i3230 fn as_error_code(err: &AApexInfoError) -> i32 {
31 match err {
32 AApexInfoError::PathNotFromApex(_) => AAPEXINFO_NO_APEX,
33 AApexInfoError::ExePathUnavailable(_) => AAPEXINFO_ERROR_GET_EXECUTABLE_PATH,
34 AApexInfoError::InvalidApex(_) => AAPEXINFO_INALID_APEX,
35 }
36 }
37
38 #[no_mangle]
39 /// Creates AApexInfo object when called by the executable from an APEX
40 ///
41 /// # Safety
42 ///
43 /// The provided pointer must be valid and have no aliases for the duration of the call.
AApexInfo_create(out: *mut *mut AApexInfo) -> i3244 pub unsafe extern "C" fn AApexInfo_create(out: *mut *mut AApexInfo) -> i32 {
45 match AApexInfo::create() {
46 Ok(info) => {
47 let ptr = Box::into_raw(Box::new(info));
48 // SAFETY: We have checked that `out` is not null, so the caller guarantees that it is
49 // valid and unaliased.
50 unsafe { *out = ptr };
51 AAPEXINFO_OK
52 }
53 Err(err) => {
54 // TODO(b/271488212): Use Rust logger.
55 eprintln!("AApexInfo_create(): {err:?}");
56 as_error_code(&err)
57 }
58 }
59 }
60
61 #[no_mangle]
62 /// Destroys AApexInfo object created by AApexInfo_create().
63 ///
64 /// # Safety
65 ///
66 /// The provided pointer must point to a valid object previously allocated by
67 /// `AApexInfo_create` (and not yet destroyed).
AApexInfo_destroy(info: *mut AApexInfo)68 pub unsafe extern "C" fn AApexInfo_destroy(info: *mut AApexInfo) {
69 // SAFETY: The pointer is not null, so the caller guarantees that it was previously returned by
70 // AApexInfo_create. AApexInfo_create got the pointer from `Box::into_raw`, so converting it
71 // back with `Box::from_raw` is valid.
72 unsafe { drop(Box::from_raw(info)) };
73 }
74
75 #[no_mangle]
76 /// Returns a C-string for APEX name.
77 ///
78 /// # Safety
79 ///
80 /// The provided pointer must point to a valid object.
AApexInfo_getName(info: *const AApexInfo) -> *const c_char81 pub unsafe extern "C" fn AApexInfo_getName(info: *const AApexInfo) -> *const c_char {
82 // SAFETY: The pointer is not null, so the caller guarantees that it is valid.
83 unsafe { (*info).name.as_ptr() }
84 }
85
86 #[no_mangle]
87 /// Returns a version of the APEX.
88 ///
89 /// # Safety
90 ///
91 /// The provided pointer must point to a valid object.
AApexInfo_getVersion(info: *const AApexInfo) -> i6492 pub unsafe extern "C" fn AApexInfo_getVersion(info: *const AApexInfo) -> i64 {
93 // SAFETY: The pointer is not null, so the caller guarantees that it is valid.
94 unsafe { (*info).version }
95 }
96