blob: 44fe39cc30701e8615207d979fa67481f1f96268 [file] [log] [blame]
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -07001/*
2 * Copyright (C) 2020 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#include "media/ShmemCompat.h"
17
18#include "binder/MemoryBase.h"
19#include "binder/MemoryHeapBase.h"
20#include "media/ShmemUtil.h"
21
22namespace android {
23namespace media {
24
25bool convertSharedFileRegionToIMemory(const SharedFileRegion& shmem,
26 sp<IMemory>* result) {
Ytai Ben-Tsvie817f392020-10-20 09:16:19 -070027 assert(result != nullptr);
28
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -070029 if (!validateSharedFileRegion(shmem)) {
30 return false;
31 }
32
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -070033 // Heap offset and size must be page aligned.
34 const size_t pageSize = getpagesize();
35 const size_t pageMask = ~(pageSize - 1);
36
37 // OK if this wraps.
38 const uint64_t endOffset = static_cast<uint64_t>(shmem.offset) +
39 static_cast<uint64_t>(shmem.size);
40
41 // Round down to page boundary.
42 const uint64_t heapStartOffset = shmem.offset & pageMask;
43 // Round up to page boundary.
44 const uint64_t heapEndOffset = (endOffset + pageSize - 1) & pageMask;
45 const uint64_t heapSize = heapEndOffset - heapStartOffset;
46
47 if (heapStartOffset > std::numeric_limits<size_t>::max() ||
48 heapSize > std::numeric_limits<size_t>::max()) {
49 return false;
50 }
51
52 const sp<MemoryHeapBase> heap =
53 new MemoryHeapBase(shmem.fd.get(), heapSize, 0, heapStartOffset);
54 *result = sp<MemoryBase>::make(heap,
55 shmem.offset - heapStartOffset,
56 shmem.size);
57 return true;
58}
59
60bool convertIMemoryToSharedFileRegion(const sp<IMemory>& mem,
61 SharedFileRegion* result) {
Ytai Ben-Tsvie817f392020-10-20 09:16:19 -070062 assert(mem != nullptr);
63 assert(result != nullptr);
64
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -070065 *result = SharedFileRegion();
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -070066
67 ssize_t offset;
68 size_t size;
69
70 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
Ytai Ben-Tsvie817f392020-10-20 09:16:19 -070071 if (size > 0) {
72 if (heap == nullptr) {
73 return false;
74 }
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -070075 // Make sure the offset and size do not overflow from int64 boundaries.
76 if (size > std::numeric_limits<int64_t>::max() ||
77 offset > std::numeric_limits<int64_t>::max() ||
78 heap->getOffset() > std::numeric_limits<int64_t>::max() ||
79 static_cast<uint64_t>(heap->getOffset()) +
80 static_cast<uint64_t>(offset)
81 > std::numeric_limits<int64_t>::max()) {
82 return false;
83 }
84
85 const int fd = fcntl(heap->getHeapID(), F_DUPFD_CLOEXEC, 0);
86 if (fd < 0) {
87 return false;
88 }
89 result->fd.reset(base::unique_fd(fd));
90 result->size = size;
91 result->offset = heap->getOffset() + offset;
92 }
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -070093 return true;
94}
95
Ytai Ben-Tsvie817f392020-10-20 09:16:19 -070096bool convertNullableSharedFileRegionToIMemory(const std::optional<SharedFileRegion>& shmem,
97 sp<IMemory>* result) {
98 assert(result != nullptr);
99
100 if (!shmem.has_value()) {
101 result->clear();
102 return true;
103 }
104
105 return convertSharedFileRegionToIMemory(shmem.value(), result);
106}
107
108bool convertNullableIMemoryToSharedFileRegion(const sp<IMemory>& mem,
109 std::optional<SharedFileRegion>* result) {
110 assert(result != nullptr);
111
112 if (mem == nullptr) {
113 result->reset();
114 return true;
115 }
116
117 result->emplace();
118 return convertIMemoryToSharedFileRegion(mem, &result->value());
119}
120
Ytai Ben-Tsvi37934a22020-08-11 15:53:04 -0700121} // namespace media
122} // namespace android