1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CPP_CAR_BINDER_LIB_LARGEPARCELABLE_INCLUDE_SHAREDMEMORY_H_
18 #define CPP_CAR_BINDER_LIB_LARGEPARCELABLE_INCLUDE_SHAREDMEMORY_H_
19 
20 #include "MappedFile.h"
21 
22 #include <android-base/unique_fd.h>
23 #include <cutils/ashmem.h>
24 #include <utils/Errors.h>
25 
26 #include <assert.h>
27 #include <unistd.h>
28 
29 #include <memory>
30 
31 namespace android {
32 namespace automotive {
33 namespace car_binder_lib {
34 
35 using ::android::status_t;
36 using ::android::base::borrowed_fd;
37 using ::android::base::unique_fd;
38 
39 // SharedMemory represents a shared memory file object.
40 class SharedMemory {
41 public:
42     // Initialize the shared memory object with the file descriptor to a shared memory file. The fd
43     // is owned by this class. Caller should use isValid() to check whether the initialization
44     // succeed and use getErr() to get error if isValid() is not true.
45     explicit SharedMemory(unique_fd fd);
46 
47     // Initialize the shared memory object with an unowned file descriptor to a shared memory file.
48     explicit SharedMemory(borrowed_fd fd);
49 
50     // Create a shared memory object with 'size'. Caller should use isValid() to check whether the
51     // initialization succeed and use getErr() to get error if isValid() is not true.
52     explicit SharedMemory(size_t size);
53 
isValid()54     inline bool isValid() const {
55         if (mOwned) {
56             return mOwnedFd.ok() && ashmem_valid(mOwnedFd.get());
57         } else {
58             return mBorrowedFd.get() >= 0 && ashmem_valid(mBorrowedFd.get());
59         }
60     }
61 
getSize()62     inline size_t getSize() const { return mSize; }
63 
getErr()64     inline status_t getErr() const { return -mErrno; }
65 
getFd()66     inline int getFd() const {
67         if (mOwned) {
68             return mOwnedFd.get();
69         }
70         return mBorrowedFd.get();
71     }
72 
getDupFd()73     inline unique_fd getDupFd() const {
74         unique_fd fd(dup(getFd()));
75         return std::move(fd);
76     }
77 
mapReadWrite()78     inline std::unique_ptr<MappedFile> mapReadWrite() const {
79         assert(!mLocked);
80         bool writable = true;
81         return std::unique_ptr<MappedFile>(new MappedFile(getFd(), mSize, writable));
82     }
83 
mapReadOnly()84     inline std::unique_ptr<MappedFile> mapReadOnly() const {
85         bool writable = false;
86         return std::unique_ptr<MappedFile>(new MappedFile(getFd(), mSize, writable));
87     }
88 
89     status_t lock();
90 
91 private:
92     unique_fd mOwnedFd;
93     borrowed_fd mBorrowedFd;
94     int mErrno = 0;
95     bool mLocked = false;
96     size_t mSize = 0;
97     bool mOwned;
98 };
99 
100 }  // namespace car_binder_lib
101 }  // namespace automotive
102 }  // namespace android
103 
104 #endif  // CPP_CAR_BINDER_LIB_LARGEPARCELABLE_INCLUDE_SHAREDMEMORY_H_
105