1 /*
2  * Copyright (c) 2023 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 Provide class Ashmem 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 #include "refbase.h"
29 #include "parcel.h"
30 
31 namespace OHOS {
32 /**
33  * @brief Create ashmem in kernel with specified name and size.
34  *
35  * @param name Name for identifying the ashmem in kernel.
36  * @param size Size of the ashmem region.
37  * @return File descriptor of the ashmem.
38  */
39 int AshmemCreate(const char *name, size_t size);
40 
41 /**
42  * @brief Set protection flag of specified ashmem region in kernel.
43 
44  * @param fd Corresponding file descriptor.
45  * @param prot Value of protection flag.
46  * @return Return 0 on success, -1 on failure.
47  */
48 int AshmemSetProt(int fd, int prot);
49 
50 /**
51  * @brief Get size of specified ashmem region in kernel.
52  *
53  * @param fd Corresponding file descriptor.
54  * @return Size of ashmem.
55  */
56 int AshmemGetSize(int fd);
57 
58 /**
59  * @brief Ashmem implemented in c_utils, to operate the
60  * Anonymous Shared Memory(Ashmem).
61  *
62  * Including create, map an ashmem region and thus write/read to/from it, etc.
63  *
64  * @note Ashmem object should be unmapped and closed manually, though managed
65  * by smart pointer.
66  */
67 class Ashmem : public virtual RefBase {
68 public:
69     /**
70      * @brief Create an Ashmem object with specified name and region size.
71      *
72      * File '/dev/ashmem' will be opened whose file descriptor will be held by
73      * this Ashmem object.
74      *
75      * @param name Name for identifying the ashmem in kernel.
76      * @param size Size of the ashmem region.
77      * @return An Ashmem object referenced by a smart pointer.
78      * @note Memory has not been mapped, use `MapAshmem()` before
79      * writing/reading.
80      */
81     static sptr<Ashmem> CreateAshmem(const char *name, int32_t size);
82 
83     /**
84      * @brief Close the ashmem(i.e. close it via file descriptor).
85      *
86      * All inner parameters will be cleared.
87      *
88      * @note An ashmem  will be unmapped first by `UnmapAshmem()` before close.
89      */
90     void CloseAshmem();
91 
92     /**
93      * @brief Map the ashmem region in the kernel to user space.
94      *
95      * @param mapType Protection flag of the mapped region in user space.
96      * @return True if mapping successful.
97      */
98     bool MapAshmem(int mapType);
99 
100     /**
101      * @brief Map the ashmem region in Read/Write mode.
102      *
103      * It calls `MapAshmem(PROT_READ | PROT_WRITE)`.
104      *
105      * @return True if mapping successful.
106      */
107     bool MapReadAndWriteAshmem();
108 
109     /**
110      * @brief Map the ashmem region in Read-Only mode.
111      *
112      * It calls `MapAshmem(PROT_READ)`.
113      *
114      * @return True if mapping successful.
115      */
116     bool MapReadOnlyAshmem();
117 
118     /**
119      * @brief Unmap the ashmem.
120      *
121      * Unmap when mapped ashmem exists, protection flag will be cleared
122      * meanwhile.
123      */
124     void UnmapAshmem();
125 
126     /**
127      * @brief Set the protection flag of ashmem region in kernel.
128      *
129      * @param protectionType Value of protection flag.
130      * @return True if set successful.
131      */
132     bool SetProtection(int protectionType);
133 
134     /**
135      * @brief Get the protection flag of ashmem region in kernel.
136      *
137      * @return Value of protection flag. Refer to linux manual.
138      */
139     int GetProtection();
140 
141     /**
142      * @brief Get the size of ashmem region in kernel.
143      *
144      * @return Value of size.
145      */
146     int32_t GetAshmemSize();
147 
148     /**
149      * @brief Write data to the `offset` position of ashmem region.
150      *
151      * Bounds and protection flag will be checked.
152      *
153      * @param data Pointer to input data.
154      * @param size Size of the input data(bytes).
155      * @param offset Offset from beginning of the region.
156      * @return True if writting successful. False if data to be write overflows
157      * or protection flag is illegal.
158      * @note Require write authority of both ashmem in kernel and the mapped
159      * one in user space.
160      */
161     bool WriteToAshmem(const void *data, int32_t size, int32_t offset);
162 
163     /**
164      * @brief Read data from the `offset` position of ashmem region.
165      *
166      * Bounds and protection flag will be checked.
167      *
168      * @param size Size of data to be read(bytes).
169      * @param offset Offset from beginning of the region.
170      * @return Void-type pointer to the data. `nullptr` returns if data to be
171      * read overflows or protection flag is illegal.
172      * @note Require read authority of both ashmem in kernel and the mapped one
173      * in user space.
174      */
175     const void *ReadFromAshmem(int32_t size, int32_t offset);
176 
177     /**
178      * @brief Construct a new Ashmem object.
179      *
180      * @param fd File descriptor of an ashmem in kenrel.
181      * @param size Size of the corresponding ashmem region in kernel.
182      */
183     Ashmem(int fd, int32_t size);
184     ~Ashmem() override;
185 
186     /**
187      * @brief Get file descriptor of the corresponding ashmem in kernel.
188      *
189      * @return Corresponding file descriptor of this Ashmem object. It will be
190      * 0 when ashmem is closed.
191      */
GetAshmemFd()192     int GetAshmemFd() const
193     {
194         return memoryFd_;
195     };
196 
197 private:
198     int memoryFd_; // corresponding file descriptor of ashmem.
199     int32_t memorySize_; // size of ashmem.
200     int flag_; // protection flag of ashmem in user space.
201     void *startAddr_; // start address of ashmem region.
202     bool CheckValid(int32_t size, int32_t offset, int cmd);
203 };
204 } // namespace OHOS
205 #endif
206