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