13f4cbf05Sopenharmony_ci// Copyright (c) 2023 Huawei Device Co., Ltd. 23f4cbf05Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 33f4cbf05Sopenharmony_ci// you may not use this file except in compliance with the License. 43f4cbf05Sopenharmony_ci// You may obtain a copy of the License at 53f4cbf05Sopenharmony_ci// 63f4cbf05Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 73f4cbf05Sopenharmony_ci// 83f4cbf05Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 93f4cbf05Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 103f4cbf05Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 113f4cbf05Sopenharmony_ci// See the License for the specific language governing permissions and 123f4cbf05Sopenharmony_ci// limitations under the License. 133f4cbf05Sopenharmony_ci 143f4cbf05Sopenharmony_ci//! Ashmem provides interfaces for operating shared memory. 153f4cbf05Sopenharmony_ci 163f4cbf05Sopenharmony_ciuse std::ffi::{c_char, CString}; 173f4cbf05Sopenharmony_ci 183f4cbf05Sopenharmony_ciuse cxx::SharedPtr; 193f4cbf05Sopenharmony_ci 203f4cbf05Sopenharmony_ci/// Memory protection corresponding to PROT_NONE in C code. 213f4cbf05Sopenharmony_cipub const PROT_NONE: i32 = 0; 223f4cbf05Sopenharmony_ci/// Memory protection corresponding to PROT_READ in C code. 233f4cbf05Sopenharmony_cipub const PROT_READ: i32 = 1; 243f4cbf05Sopenharmony_ci/// Memory protection corresponding to PROT_WRITE in C code. 253f4cbf05Sopenharmony_cipub const PROT_WRITE: i32 = 2; 263f4cbf05Sopenharmony_ci/// Memory protection corresponding to PROT_EXEC in C code. 273f4cbf05Sopenharmony_cipub const PROT_EXEC: i32 = 4; 283f4cbf05Sopenharmony_ci 293f4cbf05Sopenharmony_ci#[cxx::bridge(namespace = "OHOS")] 303f4cbf05Sopenharmony_ci/// Module Ashmem::ffi. Includes interfaces which will call c++ counterparts via 313f4cbf05Sopenharmony_ci/// FFI. 323f4cbf05Sopenharmony_cipub mod ffi { 333f4cbf05Sopenharmony_ci unsafe extern "C++" { 343f4cbf05Sopenharmony_ci include!("commonlibrary/c_utils/base/include/ashmem.h"); 353f4cbf05Sopenharmony_ci 363f4cbf05Sopenharmony_ci // global function 373f4cbf05Sopenharmony_ci /// Create an C++ Ashmem object managed by std::shared_ptr. 383f4cbf05Sopenharmony_ci /// # Safety 393f4cbf05Sopenharmony_ci /// Requires C-style string as parameter to specify the name of Ashmem. 403f4cbf05Sopenharmony_ci pub unsafe fn CreateAshmemStd(name: *const c_char, size: i32) -> SharedPtr<Ashmem>; 413f4cbf05Sopenharmony_ci 423f4cbf05Sopenharmony_ci /// Set protection flag of created ashmem specified by FD. 433f4cbf05Sopenharmony_ci pub fn AshmemSetProt(fd: i32, prot: i32) -> i32; 443f4cbf05Sopenharmony_ci 453f4cbf05Sopenharmony_ci /// Get size of created ashmem specified by FD. 463f4cbf05Sopenharmony_ci pub fn AshmemGetSize(fd: i32) -> i32; 473f4cbf05Sopenharmony_ci 483f4cbf05Sopenharmony_ci /// C++ void type. 493f4cbf05Sopenharmony_ci pub type c_void; 503f4cbf05Sopenharmony_ci /// Cast c_char to c_void 513f4cbf05Sopenharmony_ci /// # Safety 523f4cbf05Sopenharmony_ci pub unsafe fn AsVoidPtr(inPtr: *const c_char) -> *const c_void; 533f4cbf05Sopenharmony_ci 543f4cbf05Sopenharmony_ci /// Cast c_char to c_void 553f4cbf05Sopenharmony_ci /// # Safety 563f4cbf05Sopenharmony_ci pub unsafe fn AsCharPtr(inPtr: *const c_void) -> *const c_char; 573f4cbf05Sopenharmony_ci 583f4cbf05Sopenharmony_ci /// C++ Ashmem class. 593f4cbf05Sopenharmony_ci pub type Ashmem; 603f4cbf05Sopenharmony_ci 613f4cbf05Sopenharmony_ci // member function 623f4cbf05Sopenharmony_ci /// Close inner ashmem. 633f4cbf05Sopenharmony_ci pub fn CloseAshmem(self: &Ashmem) -> (); 643f4cbf05Sopenharmony_ci 653f4cbf05Sopenharmony_ci /// Map inner ashmem to user-space memory with specified map type. 663f4cbf05Sopenharmony_ci pub fn MapAshmem(self: &Ashmem, mapType: i32) -> bool; 673f4cbf05Sopenharmony_ci 683f4cbf05Sopenharmony_ci /// Map inner ashmem to user-space memory with read-write type. 693f4cbf05Sopenharmony_ci pub fn MapReadAndWriteAshmem(self: &Ashmem) -> bool; 703f4cbf05Sopenharmony_ci 713f4cbf05Sopenharmony_ci /// Map inner ashmem to user-space memory with read-only type. 723f4cbf05Sopenharmony_ci pub fn MapReadOnlyAshmem(self: &Ashmem) -> bool; 733f4cbf05Sopenharmony_ci 743f4cbf05Sopenharmony_ci /// UnMap inner ashmem. 753f4cbf05Sopenharmony_ci pub fn UnmapAshmem(self: &Ashmem) -> (); 763f4cbf05Sopenharmony_ci 773f4cbf05Sopenharmony_ci /// Set protection flag of inner ashmem. 783f4cbf05Sopenharmony_ci pub fn SetProtection(self: &Ashmem, protType: i32) -> bool; 793f4cbf05Sopenharmony_ci 803f4cbf05Sopenharmony_ci /// Get protection flag of inner ashmem. 813f4cbf05Sopenharmony_ci pub fn GetProtection(self: &Ashmem) -> i32; 823f4cbf05Sopenharmony_ci 833f4cbf05Sopenharmony_ci /// Get size of inner ashmem. 843f4cbf05Sopenharmony_ci pub fn GetAshmemSize(self: &Ashmem) -> i32; 853f4cbf05Sopenharmony_ci 863f4cbf05Sopenharmony_ci /// Write data to inner ashmem. 873f4cbf05Sopenharmony_ci /// # Safety 883f4cbf05Sopenharmony_ci /// Requires a C++-style void pointer as parameter to indicates data 893f4cbf05Sopenharmony_ci /// expected to be written. 903f4cbf05Sopenharmony_ci pub unsafe fn WriteToAshmem( 913f4cbf05Sopenharmony_ci self: &Ashmem, 923f4cbf05Sopenharmony_ci data: *const c_void, 933f4cbf05Sopenharmony_ci size: i32, 943f4cbf05Sopenharmony_ci offset: i32, 953f4cbf05Sopenharmony_ci ) -> bool; 963f4cbf05Sopenharmony_ci 973f4cbf05Sopenharmony_ci /// Read data from inner ashmem. 983f4cbf05Sopenharmony_ci /// # Safety 993f4cbf05Sopenharmony_ci /// Returns a C++-style void pointer to indicates data expected to be 1003f4cbf05Sopenharmony_ci /// read. 1013f4cbf05Sopenharmony_ci pub unsafe fn ReadFromAshmem(self: &Ashmem, size: i32, offset: i32) -> *const c_void; 1023f4cbf05Sopenharmony_ci 1033f4cbf05Sopenharmony_ci /// Get FD of inner ashmem. 1043f4cbf05Sopenharmony_ci pub fn GetAshmemFd(self: &Ashmem) -> i32; 1053f4cbf05Sopenharmony_ci } 1063f4cbf05Sopenharmony_ci} 1073f4cbf05Sopenharmony_ci 1083f4cbf05Sopenharmony_ci/// Ashmem in rust. 1093f4cbf05Sopenharmony_cipub struct Ashmem { 1103f4cbf05Sopenharmony_ci c_ashmem: SharedPtr<ffi::Ashmem>, 1113f4cbf05Sopenharmony_ci} 1123f4cbf05Sopenharmony_ci 1133f4cbf05Sopenharmony_ci/// Ashmem implementation. 1143f4cbf05Sopenharmony_ciimpl Ashmem { 1153f4cbf05Sopenharmony_ci /// Create an ashmem object. 1163f4cbf05Sopenharmony_ci pub fn new(c_ashmem: SharedPtr<ffi::Ashmem>) -> Ashmem { 1173f4cbf05Sopenharmony_ci Ashmem { c_ashmem } 1183f4cbf05Sopenharmony_ci } 1193f4cbf05Sopenharmony_ci 1203f4cbf05Sopenharmony_ci /// Get corresponding fd. 1213f4cbf05Sopenharmony_ci pub fn get_ashmem_fd(&self) -> i32 { 1223f4cbf05Sopenharmony_ci self.c_ashmem.GetAshmemFd() 1233f4cbf05Sopenharmony_ci } 1243f4cbf05Sopenharmony_ci 1253f4cbf05Sopenharmony_ci /// Get size of the shared memory. 1263f4cbf05Sopenharmony_ci pub fn get_ashmem_size(&self) -> i32 { 1273f4cbf05Sopenharmony_ci self.c_ashmem.GetAshmemSize() 1283f4cbf05Sopenharmony_ci } 1293f4cbf05Sopenharmony_ci 1303f4cbf05Sopenharmony_ci /// Get memory protection flags. 1313f4cbf05Sopenharmony_ci pub fn get_protection(&self) -> i32 { 1323f4cbf05Sopenharmony_ci self.c_ashmem.GetProtection() 1333f4cbf05Sopenharmony_ci } 1343f4cbf05Sopenharmony_ci 1353f4cbf05Sopenharmony_ci /// Set memory protection flags. 1363f4cbf05Sopenharmony_ci pub fn set_protection(&self, prot_type: i32) -> bool { 1373f4cbf05Sopenharmony_ci self.c_ashmem.SetProtection(prot_type) 1383f4cbf05Sopenharmony_ci } 1393f4cbf05Sopenharmony_ci 1403f4cbf05Sopenharmony_ci /// Map the shared memory to user-space. 1413f4cbf05Sopenharmony_ci pub fn map_ashmem(&self, prot_type: i32) -> bool { 1423f4cbf05Sopenharmony_ci self.c_ashmem.MapAshmem(prot_type) 1433f4cbf05Sopenharmony_ci } 1443f4cbf05Sopenharmony_ci 1453f4cbf05Sopenharmony_ci /// Map ashmem in read&write mode. 1463f4cbf05Sopenharmony_ci pub fn map_read_write_ashmem(&self) -> bool { 1473f4cbf05Sopenharmony_ci self.c_ashmem.MapReadAndWriteAshmem() 1483f4cbf05Sopenharmony_ci } 1493f4cbf05Sopenharmony_ci 1503f4cbf05Sopenharmony_ci /// Map ashmem in read-only mode. 1513f4cbf05Sopenharmony_ci pub fn map_read_only_ashmem(&self) -> bool { 1523f4cbf05Sopenharmony_ci self.c_ashmem.MapReadOnlyAshmem() 1533f4cbf05Sopenharmony_ci } 1543f4cbf05Sopenharmony_ci 1553f4cbf05Sopenharmony_ci /// Unmap ashmem. 1563f4cbf05Sopenharmony_ci pub fn unmap_ashmem(&self) { 1573f4cbf05Sopenharmony_ci self.c_ashmem.UnmapAshmem() 1583f4cbf05Sopenharmony_ci } 1593f4cbf05Sopenharmony_ci 1603f4cbf05Sopenharmony_ci /// Close ashmem. 1613f4cbf05Sopenharmony_ci pub fn close_ashmem(&self) { 1623f4cbf05Sopenharmony_ci self.c_ashmem.CloseAshmem() 1633f4cbf05Sopenharmony_ci } 1643f4cbf05Sopenharmony_ci 1653f4cbf05Sopenharmony_ci /// Write data to ashmem. 1663f4cbf05Sopenharmony_ci /// # Safety 1673f4cbf05Sopenharmony_ci /// Requires c-style data(*const c_char) 1683f4cbf05Sopenharmony_ci pub unsafe fn write_to_ashmem(&self, data: *const c_char, size: i32, offset: i32) -> bool { 1693f4cbf05Sopenharmony_ci let c_void_ptr = ffi::AsVoidPtr(data); 1703f4cbf05Sopenharmony_ci self.c_ashmem.WriteToAshmem(c_void_ptr, size, offset) 1713f4cbf05Sopenharmony_ci } 1723f4cbf05Sopenharmony_ci 1733f4cbf05Sopenharmony_ci /// Gets inner c_ashemem. 1743f4cbf05Sopenharmony_ci /// 1753f4cbf05Sopenharmony_ci /// # Safety 1763f4cbf05Sopenharmony_ci /// Returns c++ opaque shared ptr. 1773f4cbf05Sopenharmony_ci pub unsafe fn c_ashmem(&self) -> &SharedPtr<ffi::Ashmem> { 1783f4cbf05Sopenharmony_ci &self.c_ashmem 1793f4cbf05Sopenharmony_ci } 1803f4cbf05Sopenharmony_ci 1813f4cbf05Sopenharmony_ci /// Read data from ashmem. 1823f4cbf05Sopenharmony_ci /// # Safety 1833f4cbf05Sopenharmony_ci /// Returns c-style data(*const c_char) 1843f4cbf05Sopenharmony_ci pub unsafe fn read_from_ashmem(&self, size: i32, offset: i32) -> *const c_char { 1853f4cbf05Sopenharmony_ci let c_void_ptr = self.c_ashmem.ReadFromAshmem(size, offset); 1863f4cbf05Sopenharmony_ci ffi::AsCharPtr(c_void_ptr) 1873f4cbf05Sopenharmony_ci } 1883f4cbf05Sopenharmony_ci} 1893f4cbf05Sopenharmony_ci 1903f4cbf05Sopenharmony_ci/// Create Ashmem struct in Rust, which holds a refrence to c++ Ashmem object. 1913f4cbf05Sopenharmony_ci/// # Safety 1923f4cbf05Sopenharmony_ci/// Transmits c-style string of `name`. 1933f4cbf05Sopenharmony_cipub unsafe fn create_ashmem_instance(name: &str, size: i32) -> Option<Ashmem> { 1943f4cbf05Sopenharmony_ci let c_name = CString::new(name).expect("CString::new Failed!"); 1953f4cbf05Sopenharmony_ci let name_ptr = c_name.as_ptr(); 1963f4cbf05Sopenharmony_ci let c_ashmem_ptr = ffi::CreateAshmemStd(name_ptr, size); 1973f4cbf05Sopenharmony_ci 1983f4cbf05Sopenharmony_ci if c_ashmem_ptr.is_null() { 1993f4cbf05Sopenharmony_ci None 2003f4cbf05Sopenharmony_ci } else { 2013f4cbf05Sopenharmony_ci Some(Ashmem::new(c_ashmem_ptr)) 2023f4cbf05Sopenharmony_ci } 2033f4cbf05Sopenharmony_ci} 204