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
16 use std::ffi::{c_char, CString};
17
18 use cxx::SharedPtr;
19
20 /// Memory protection corresponding to PROT_NONE in C code.
21 pub const PROT_NONE: i32 = 0;
22 /// Memory protection corresponding to PROT_READ in C code.
23 pub const PROT_READ: i32 = 1;
24 /// Memory protection corresponding to PROT_WRITE in C code.
25 pub const PROT_WRITE: i32 = 2;
26 /// Memory protection corresponding to PROT_EXEC in C code.
27 pub 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.
32 pub 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.
CreateAshmemStd(name: *const c_char, size: i32) -> SharedPtr<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.
AshmemSetProt(fd: i32, prot: i32) -> i3243 pub fn AshmemSetProt(fd: i32, prot: i32) -> i32;
44
45 /// Get size of created ashmem specified by FD.
AshmemGetSize(fd: i32) -> i3246 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
AsVoidPtr(inPtr: *const c_char) -> *const c_void52 pub unsafe fn AsVoidPtr(inPtr: *const c_char) -> *const c_void;
53
54 /// Cast c_char to c_void
55 /// # Safety
AsCharPtr(inPtr: *const c_void) -> *const c_char56 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.
CloseAshmem(self: &Ashmem) -> ()63 pub fn CloseAshmem(self: &Ashmem) -> ();
64
65 /// Map inner ashmem to user-space memory with specified map type.
MapAshmem(self: &Ashmem, mapType: i32) -> bool66 pub fn MapAshmem(self: &Ashmem, mapType: i32) -> bool;
67
68 /// Map inner ashmem to user-space memory with read-write type.
MapReadAndWriteAshmem(self: &Ashmem) -> bool69 pub fn MapReadAndWriteAshmem(self: &Ashmem) -> bool;
70
71 /// Map inner ashmem to user-space memory with read-only type.
MapReadOnlyAshmem(self: &Ashmem) -> bool72 pub fn MapReadOnlyAshmem(self: &Ashmem) -> bool;
73
74 /// UnMap inner ashmem.
UnmapAshmem(self: &Ashmem) -> ()75 pub fn UnmapAshmem(self: &Ashmem) -> ();
76
77 /// Set protection flag of inner ashmem.
SetProtection(self: &Ashmem, protType: i32) -> bool78 pub fn SetProtection(self: &Ashmem, protType: i32) -> bool;
79
80 /// Get protection flag of inner ashmem.
GetProtection(self: &Ashmem) -> i3281 pub fn GetProtection(self: &Ashmem) -> i32;
82
83 /// Get size of inner ashmem.
GetAshmemSize(self: &Ashmem) -> i3284 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.
WriteToAshmem( self: &Ashmem, data: *const c_void, size: i32, offset: i32, ) -> bool90 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.
ReadFromAshmem(self: &Ashmem, size: i32, offset: i32) -> *const c_void101 pub unsafe fn ReadFromAshmem(self: &Ashmem, size: i32, offset: i32) -> *const c_void;
102
103 /// Get FD of inner ashmem.
GetAshmemFd(self: &Ashmem) -> i32104 pub fn GetAshmemFd(self: &Ashmem) -> i32;
105 }
106 }
107
108 /// Ashmem in rust.
109 pub struct Ashmem {
110 c_ashmem: SharedPtr<ffi::Ashmem>,
111 }
112
113 /// Ashmem implementation.
114 impl Ashmem {
115 /// Create an ashmem object.
new(c_ashmem: SharedPtr<ffi::Ashmem>) -> Ashmem116 pub fn new(c_ashmem: SharedPtr<ffi::Ashmem>) -> Ashmem {
117 Ashmem { c_ashmem }
118 }
119
120 /// Get corresponding fd.
get_ashmem_fd(&self) -> i32121 pub fn get_ashmem_fd(&self) -> i32 {
122 self.c_ashmem.GetAshmemFd()
123 }
124
125 /// Get size of the shared memory.
get_ashmem_size(&self) -> i32126 pub fn get_ashmem_size(&self) -> i32 {
127 self.c_ashmem.GetAshmemSize()
128 }
129
130 /// Get memory protection flags.
get_protection(&self) -> i32131 pub fn get_protection(&self) -> i32 {
132 self.c_ashmem.GetProtection()
133 }
134
135 /// Set memory protection flags.
set_protection(&self, prot_type: i32) -> bool136 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.
map_ashmem(&self, prot_type: i32) -> bool141 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.
map_read_write_ashmem(&self) -> bool146 pub fn map_read_write_ashmem(&self) -> bool {
147 self.c_ashmem.MapReadAndWriteAshmem()
148 }
149
150 /// Map ashmem in read-only mode.
map_read_only_ashmem(&self) -> bool151 pub fn map_read_only_ashmem(&self) -> bool {
152 self.c_ashmem.MapReadOnlyAshmem()
153 }
154
155 /// Unmap ashmem.
unmap_ashmem(&self)156 pub fn unmap_ashmem(&self) {
157 self.c_ashmem.UnmapAshmem()
158 }
159
160 /// Close ashmem.
close_ashmem(&self)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)
write_to_ashmem(&self, data: *const c_char, size: i32, offset: i32) -> bool168 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.
c_ashmem(&self) -> &SharedPtr<ffi::Ashmem>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)
read_from_ashmem(&self, size: i32, offset: i32) -> *const c_char184 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`.
create_ashmem_instance(name: &str, size: i32) -> Option<Ashmem>193 pub 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