1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16  /**
17  * @file ashmem.h
18  *
19  * @brief Provides the <b>Ashmem</b> class implemented in c_utils to operate the
20  * Anonymous Shared Memory (Ashmem).
21  */
22 
23 #ifndef UTILS_BASE_ASHMEM_H
24 #define UTILS_BASE_ASHMEM_H
25 
26 #include <cstddef>
27 #include <linux/ashmem.h>
28 #ifdef UTILS_CXX_RUST
29 #include <memory>
30 #endif
31 #include "refbase.h"
32 #include "parcel.h"
33 
34 namespace OHOS {
35 class Ashmem;
36 
37 #ifdef UTILS_CXX_RUST
38 using c_void = void;
39 const c_void* AsVoidPtr(const char* inPtr);
40 const char* AsCharPtr(const c_void* inPtr);
41 std::shared_ptr<Ashmem> CreateAshmemStd(const char *name, int32_t size);
42 #endif
43 
44 /**
45  * @brief Creates an <b>Ashmem</b> region in the kernel.
46  *
47  * @param name Indicates the pointer to the name that will be
48  * copied and assigned to the <b>Ashmem</b> region in the kernel.
49  * @param size Indicates the size of the <b>Ashmem</b> region to create.
50  * @return Returns the file descriptor of the <b>Ashmem</b> region.
51  */
52 int AshmemCreate(const char *name, size_t size);
53 
54 /**
55  * @brief Sets the protection flag of an <b>Ashmem</b> region in the kernel.
56  *
57  * @param fd Indicates the file descriptor of an <b>Ashmem</b> region.
58  * @param prot Indicates the value of the protection flag.
59  * @return Returns <b>0</b> if the operation is successful;
60  * returns <b>-1</b> otherwise.
61  */
62 int AshmemSetProt(int fd, int prot);
63 
64 /**
65  * @brief Obtains the size of a specific <b>Ashmem</b> region in the kernel.
66  *
67  * @param fd Indicates the file descriptor of an <b>Ashmem</b> region.
68  * @return Returns the size of the <b>Ashmem</b> region.
69  */
70 int AshmemGetSize(int fd);
71 
72 /**
73  * @brief Provides the <b>Ashmem</b> class implemented in c_utils to
74  * operate the Anonymous Shared Memory (Ashmem).
75  *
76  * You can use the interfaces in this class to create <b>Ashmem</b> regions
77  * and map them to implement write and read operations.
78  *
79  * @note <b>Ashmem</b> regions should be unmapped and closed manually,
80  * though managed by a smart pointer.
81  */
82 class Ashmem : public virtual RefBase {
83 public:
84     /**
85      * @brief Creates an <b>Ashmem</b> region in the kernel.
86      *
87      * The <b>/dev/ashmem</b> file will be opened, whose file
88      * descriptor will be held by the created <b>Ashmem</b> region.
89      *
90      * @param name Indicates the pointer to the name that will be
91 	 * copied and assigned to the <b>Ashmem</b> region in the kernel.
92      * @param size Indicates the size of the <b>Ashmem</b> region.
93      * @return Returns the created <b>Ashmem</b> region referenced by a
94      * smart pointer.
95      * @note Before writing/reading data in the region, use `MapAshmem()`.
96      *
97      */
98     static sptr<Ashmem> CreateAshmem(const char *name, int32_t size);
99 
100     /**
101      * @brief Construct a new Ashmem object.
102      *
103      * @param fd File descriptor of an ashmem in kenrel.
104      * @param size Size of the corresponding ashmem region in kernel.
105      */
106     Ashmem(int fd, int32_t size);
107     ~Ashmem() override;
108 
109     /**
110      * @brief Get file descriptor of the corresponding ashmem in kernel.
111      *
112      * @return Corresponding file descriptor of this Ashmem object. It will be
113      * 0 when ashmem is closed.
114      */
GetAshmemFd()115     int GetAshmemFd() const
116     {
117         return memoryFd_;
118     };
119 
120     /**
121      * @brief Set the protection flag of ashmem region in kernel.
122      *
123      * @param protectionType Value of protection flag.
124      * @return True if set successful.
125      */
126     bool SetProtection(int protectionType) const;
127 
128     /**
129      * @brief Get the protection flag of ashmem region in kernel.
130      *
131      * @return Value of protection flag. Refer to linux manual.
132      */
133     int GetProtection() const;
134 
135     /**
136      * @brief Get the size of ashmem region in kernel.
137      *
138      * @return Value of size.
139      */
140     int32_t GetAshmemSize() const;
141 
142     #ifdef UTILS_CXX_RUST
143     void CloseAshmem() const;
144     bool MapAshmem(int mapType) const;
145     bool MapReadAndWriteAshmem() const;
146     bool MapReadOnlyAshmem() const;
147     void UnmapAshmem() const;
148     bool WriteToAshmem(const void *data, int32_t size, int32_t offset) const;
149     const void *ReadFromAshmem(int32_t size, int32_t offset) const;
150     #else
151     /**
152      * @brief Closes this <b>Ashmem</b> region (through the file descriptor).
153      *
154      * All inner parameters will be cleared.
155      *
156      * @note An <b>Ashmem</b> region will be unmapped by `UnmapAshmem()`
157 	 * before being closed.
158      */
159     void CloseAshmem();
160 
161     /**
162      * @brief Maps this <b>Ashmem</b> region in the kernel to user space.
163      *
164      * @param mapType Indicates the protection flag of the mapped region in
165      * user space.
166      * @return Returns <b>true</b> if mapping is successful.
167      */
168     bool MapAshmem(int mapType);
169 
170     /**
171      * @brief Maps this <b>Ashmem</b> region in read/write mode.
172      *
173      * It calls `MapAshmem(PROT_READ | PROT_WRITE)`.
174      *
175      * @return Returns <b>true</b> if mapping is successful.
176      */
177     bool MapReadAndWriteAshmem();
178 
179     /**
180      * @brief Maps this <b>Ashmem</b> region in read-only mode.
181      *
182      * It calls `MapAshmem(PROT_READ)`.
183      *
184      * @return Returns <b>true</b> if mapping is successful.
185      */
186     bool MapReadOnlyAshmem();
187 
188     /**
189      * @brief Unmaps this <b>Ashmem</b> region.
190      *
191      * Unmapping works only when the <b>Ashmem</b> region has been mapped.
192      * It will clear the protection flag.
193      */
194     void UnmapAshmem();
195 
196     /**
197      * @brief Writes data to the `offset` position of this <b>Ashmem</b> region.
198      *
199      * Bounds and the protection flag will be checked.
200      *
201      * @param data Indicates the pointer to the data to write.
202      * @param size Indicates the size of the data to write, in bytes.
203      * @param offset Indicates the offset from the start position of the
204 	 * <b>Ashmem</b> region.
205      * @return Returns <b>True</b> if the operation is successful; returns
206      * <b>False</b> if overflow occurs or the protection flag is illegal.
207      * @note This operation requires the write permission on both the
208      * <b>Ashmem</b> region in the kernel and the mapped region in user space.
209      */
210     bool WriteToAshmem(const void *data, int32_t size, int32_t offset);
211 
212     /**
213      * @brief Reads data from the `offset` position of this <b>Ashmem</b> region.
214      *
215      * Bounds and the protection flag will be checked.
216      *
217      * @param size Indicates the size of the data to read, in bytes.
218      * @param offset Indicates the offset from the start position of
219 	 * the <b>Ashmem</b> region.
220      * @return Returns the void-type pointer to the data. `nullptr` is returned
221      * if overflow occurs or the protection flag is illegal.
222      * @note This operation requires the read permission on both the
223      * <b>Ashmem</b> region in the kernel and the mapped region in user space.
224      */
225     const void *ReadFromAshmem(int32_t size, int32_t offset);
226     #endif
227 private:
228     #ifdef UTILS_CXX_RUST
229     mutable int memoryFd_; // File descriptor of the Ashmem region.
230     mutable int32_t memorySize_; // Size of the Ashmem region.
231     mutable int flag_; // Protection flag of the Ashmem region in user space.
232     mutable void *startAddr_; // Start address of the Ashmem region.
233     #else
234     int memoryFd_; // File descriptor of the Ashmem region.
235     int32_t memorySize_; // Size of the Ashmem region.
236     int flag_; // Protection flag of the Ashmem region in user space.
237     void *startAddr_; // Start address of the Ashmem region.
238     #endif
239 
240     bool CheckValid(int32_t size, int32_t offset, int cmd) const;
241 };
242 } // namespace OHOS
243 #endif