xref: /commonlibrary/c_utils/base/src/rust/ashmem.rs (revision 3f4cbf05)
1// Copyright (c) 2023 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14//! Ashmem provides interfaces for operating shared memory.
15
16use std::ffi::{c_char, CString};
17
18use cxx::SharedPtr;
19
20/// Memory protection corresponding to PROT_NONE in C code.
21pub const PROT_NONE: i32 = 0;
22/// Memory protection corresponding to PROT_READ in C code.
23pub const PROT_READ: i32 = 1;
24/// Memory protection corresponding to PROT_WRITE in C code.
25pub const PROT_WRITE: i32 = 2;
26/// Memory protection corresponding to PROT_EXEC in C code.
27pub const PROT_EXEC: i32 = 4;
28
29#[cxx::bridge(namespace = "OHOS")]
30/// Module Ashmem::ffi. Includes interfaces which will call c++ counterparts via
31/// FFI.
32pub mod ffi {
33    unsafe extern "C++" {
34        include!("commonlibrary/c_utils/base/include/ashmem.h");
35
36        // global function
37        /// Create an C++ Ashmem object managed by std::shared_ptr.
38        /// # Safety
39        /// Requires C-style string as parameter to specify the name of Ashmem.
40        pub unsafe fn CreateAshmemStd(name: *const c_char, size: i32) -> SharedPtr<Ashmem>;
41
42        /// Set protection flag of created ashmem specified by FD.
43        pub fn AshmemSetProt(fd: i32, prot: i32) -> i32;
44
45        /// Get size of created ashmem specified by FD.
46        pub fn AshmemGetSize(fd: i32) -> i32;
47
48        /// C++ void type.
49        pub type c_void;
50        /// Cast c_char to c_void
51        /// # Safety
52        pub unsafe fn AsVoidPtr(inPtr: *const c_char) -> *const c_void;
53
54        /// Cast c_char to c_void
55        /// # Safety
56        pub unsafe fn AsCharPtr(inPtr: *const c_void) -> *const c_char;
57
58        /// C++ Ashmem class.
59        pub type Ashmem;
60
61        // member function
62        /// Close inner ashmem.
63        pub fn CloseAshmem(self: &Ashmem) -> ();
64
65        /// Map inner ashmem to user-space memory with specified map type.
66        pub fn MapAshmem(self: &Ashmem, mapType: i32) -> bool;
67
68        /// Map inner ashmem to user-space memory with read-write type.
69        pub fn MapReadAndWriteAshmem(self: &Ashmem) -> bool;
70
71        /// Map inner ashmem to user-space memory with read-only type.
72        pub fn MapReadOnlyAshmem(self: &Ashmem) -> bool;
73
74        /// UnMap inner ashmem.
75        pub fn UnmapAshmem(self: &Ashmem) -> ();
76
77        /// Set protection flag of inner ashmem.
78        pub fn SetProtection(self: &Ashmem, protType: i32) -> bool;
79
80        /// Get protection flag of inner ashmem.
81        pub fn GetProtection(self: &Ashmem) -> i32;
82
83        /// Get size of inner ashmem.
84        pub fn GetAshmemSize(self: &Ashmem) -> i32;
85
86        /// Write data to inner ashmem.
87        /// # Safety
88        /// Requires a C++-style void pointer as parameter to indicates data
89        /// expected to be written.
90        pub unsafe fn WriteToAshmem(
91            self: &Ashmem,
92            data: *const c_void,
93            size: i32,
94            offset: i32,
95        ) -> bool;
96
97        /// Read data from inner ashmem.
98        /// # Safety
99        /// Returns a C++-style void pointer to indicates data expected to be
100        /// read.
101        pub unsafe fn ReadFromAshmem(self: &Ashmem, size: i32, offset: i32) -> *const c_void;
102
103        /// Get FD of inner ashmem.
104        pub fn GetAshmemFd(self: &Ashmem) -> i32;
105    }
106}
107
108/// Ashmem in rust.
109pub struct Ashmem {
110    c_ashmem: SharedPtr<ffi::Ashmem>,
111}
112
113/// Ashmem implementation.
114impl Ashmem {
115    /// Create an ashmem object.
116    pub fn new(c_ashmem: SharedPtr<ffi::Ashmem>) -> Ashmem {
117        Ashmem { c_ashmem }
118    }
119
120    /// Get corresponding fd.
121    pub fn get_ashmem_fd(&self) -> i32 {
122        self.c_ashmem.GetAshmemFd()
123    }
124
125    /// Get size of the shared memory.
126    pub fn get_ashmem_size(&self) -> i32 {
127        self.c_ashmem.GetAshmemSize()
128    }
129
130    /// Get memory protection flags.
131    pub fn get_protection(&self) -> i32 {
132        self.c_ashmem.GetProtection()
133    }
134
135    /// Set memory protection flags.
136    pub fn set_protection(&self, prot_type: i32) -> bool {
137        self.c_ashmem.SetProtection(prot_type)
138    }
139
140    /// Map the shared memory to user-space.
141    pub fn map_ashmem(&self, prot_type: i32) -> bool {
142        self.c_ashmem.MapAshmem(prot_type)
143    }
144
145    /// Map ashmem in read&write mode.
146    pub fn map_read_write_ashmem(&self) -> bool {
147        self.c_ashmem.MapReadAndWriteAshmem()
148    }
149
150    /// Map ashmem in read-only mode.
151    pub fn map_read_only_ashmem(&self) -> bool {
152        self.c_ashmem.MapReadOnlyAshmem()
153    }
154
155    /// Unmap ashmem.
156    pub fn unmap_ashmem(&self) {
157        self.c_ashmem.UnmapAshmem()
158    }
159
160    /// Close ashmem.
161    pub fn close_ashmem(&self) {
162        self.c_ashmem.CloseAshmem()
163    }
164
165    /// Write data to ashmem.
166    /// # Safety
167    /// Requires c-style data(*const c_char)
168    pub unsafe fn write_to_ashmem(&self, data: *const c_char, size: i32, offset: i32) -> bool {
169        let c_void_ptr = ffi::AsVoidPtr(data);
170        self.c_ashmem.WriteToAshmem(c_void_ptr, size, offset)
171    }
172
173    /// Gets inner c_ashemem.
174    ///
175    /// # Safety
176    /// Returns c++ opaque shared ptr.
177    pub unsafe fn c_ashmem(&self) -> &SharedPtr<ffi::Ashmem> {
178        &self.c_ashmem
179    }
180
181    /// Read data from ashmem.
182    /// # Safety
183    /// Returns c-style data(*const c_char)
184    pub unsafe fn read_from_ashmem(&self, size: i32, offset: i32) -> *const c_char {
185        let c_void_ptr = self.c_ashmem.ReadFromAshmem(size, offset);
186        ffi::AsCharPtr(c_void_ptr)
187    }
188}
189
190/// Create Ashmem struct in Rust, which holds a refrence to c++ Ashmem object.
191/// # Safety
192/// Transmits c-style string of `name`.
193pub unsafe fn create_ashmem_instance(name: &str, size: i32) -> Option<Ashmem> {
194    let c_name = CString::new(name).expect("CString::new Failed!");
195    let name_ptr = c_name.as_ptr();
196    let c_ashmem_ptr = ffi::CreateAshmemStd(name_ptr, size);
197
198    if c_ashmem_ptr.is_null() {
199        None
200    } else {
201        Some(Ashmem::new(c_ashmem_ptr))
202    }
203}
204