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