1 /*
2  * Copyright (C) 2018 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 ANDROID_BUFFER_HUB_METADATA_H_
18 #define ANDROID_BUFFER_HUB_METADATA_H_
19 
20 #include <android-base/unique_fd.h>
21 #include <ui/BufferHubDefs.h>
22 
23 namespace android {
24 
25 namespace {
26 using base::unique_fd;
27 } // namespace
28 
29 class BufferHubMetadata {
30 public:
31     // Creates a new BufferHubMetadata backed by an ashmem region.
32     //
33     // @param userMetadataSize Size in bytes of the user defined metadata. The entire metadata
34     //        shared memory region to be allocated is the size of canonical
35     //        BufferHubDefs::MetadataHeader plus userMetadataSize.
36     static BufferHubMetadata create(size_t userMetadataSize);
37 
38     // Imports an existing BufferHubMetadata from an ashmem FD.
39     //
40     // @param ashmemFd Ashmem file descriptor representing an ashmem region.
41     static BufferHubMetadata import(unique_fd ashmemFd);
42 
43     BufferHubMetadata() = default;
44 
BufferHubMetadata(BufferHubMetadata && other)45     BufferHubMetadata(BufferHubMetadata&& other) { *this = std::move(other); }
46 
47     ~BufferHubMetadata();
48 
49     BufferHubMetadata& operator=(BufferHubMetadata&& other) {
50         if (this != &other) {
51             mUserMetadataSize = other.mUserMetadataSize;
52             other.mUserMetadataSize = 0;
53 
54             mAshmemFd = std::move(other.mAshmemFd);
55 
56             // The old raw mMetadataHeader pointer must be cleared, otherwise the destructor will
57             // automatically mummap() the shared memory.
58             mMetadataHeader = other.mMetadataHeader;
59             other.mMetadataHeader = nullptr;
60         }
61         return *this;
62     }
63 
64     // Returns true if the metadata is valid, i.e. the metadata has a valid ashmem fd and the ashmem
65     // has been mapped into virtual address space.
isValid()66     bool isValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; }
67 
userMetadataSize()68     size_t userMetadataSize() const { return mUserMetadataSize; }
metadataSize()69     size_t metadataSize() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; }
70 
ashmemFd()71     const unique_fd& ashmemFd() const { return mAshmemFd; }
metadataHeader()72     BufferHubDefs::MetadataHeader* metadataHeader() { return mMetadataHeader; }
73 
74 private:
75     BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd,
76                       BufferHubDefs::MetadataHeader* metadataHeader);
77 
78     BufferHubMetadata(const BufferHubMetadata&) = delete;
79     void operator=(const BufferHubMetadata&) = delete;
80 
81     size_t mUserMetadataSize = 0;
82     unique_fd mAshmemFd;
83     BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr;
84 };
85 
86 } // namespace android
87 
88 #endif // ANDROID_BUFFER_HUB_METADATA_H_
89