• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 <gtest/gtest.h>
17 
18 #include "binder/MemoryBase.h"
19 #include "binder/MemoryHeapBase.h"
20 #include "cutils/ashmem.h"
21 #include "media/ShmemCompat.h"
22 #include "media/ShmemUtil.h"
23 
24 namespace android {
25 namespace media {
26 namespace {
27 
28 // Creates a SharedFileRegion instance.
makeSharedFileRegion(int64_t offset,int64_t size)29 SharedFileRegion makeSharedFileRegion(int64_t offset, int64_t size) {
30     SharedFileRegion shmem;
31     shmem.offset = offset;
32     shmem.size = size;
33     int fd = ashmem_create_region("", size + offset);
34     assert(fd >= 0);
35     shmem.fd = os::ParcelFileDescriptor(base::unique_fd(fd));
36     return shmem;
37 }
38 
39 // Creates a SharedFileRegion instance with an invalid FD.
makeInvalidSharedFileRegion(int64_t offset,int64_t size)40 SharedFileRegion makeInvalidSharedFileRegion(int64_t offset, int64_t size) {
41     SharedFileRegion shmem;
42     shmem.offset = offset;
43     shmem.size = size;
44     return shmem;
45 }
46 
makeIMemory(const std::vector<uint8_t> & content,bool writeable=true)47 sp<IMemory> makeIMemory(const std::vector<uint8_t>& content, bool writeable = true) {
48     constexpr size_t kOffset = 19;
49 
50     sp<MemoryHeapBase> heap = new MemoryHeapBase(content.size(),
51                                                  !writeable ? IMemoryHeap::READ_ONLY : 0);
52     sp<IMemory> result = sp<MemoryBase>::make(heap, kOffset, content.size());
53     memcpy(result->unsecurePointer(), content.data(), content.size());
54     return result;
55 }
56 
TEST(ShmemTest,Validate)57 TEST(ShmemTest, Validate) {
58     EXPECT_TRUE(validateSharedFileRegion(makeSharedFileRegion(0, 0)));
59     EXPECT_TRUE(validateSharedFileRegion(makeSharedFileRegion(1, 2)));
60     EXPECT_FALSE(validateSharedFileRegion(makeSharedFileRegion(-1, 2)));
61     EXPECT_FALSE(validateSharedFileRegion(makeSharedFileRegion(2, -1)));
62     EXPECT_FALSE(validateSharedFileRegion(makeInvalidSharedFileRegion(1, 2)));
63 }
64 
TEST(ShmemTest,Conversion)65 TEST(ShmemTest, Conversion) {
66     sp<IMemory> reconstructed;
67     {
68         SharedFileRegion shmem;
69         sp<IMemory> imem = makeIMemory({6, 5, 3});
70         ASSERT_TRUE(convertIMemoryToSharedFileRegion(imem, &shmem));
71         ASSERT_EQ(3, shmem.size);
72         ASSERT_GE(shmem.fd.get(), 0);
73         ASSERT_TRUE(shmem.writeable);
74         ASSERT_TRUE(convertSharedFileRegionToIMemory(shmem, &reconstructed));
75     }
76     ASSERT_EQ(3, reconstructed->size());
77     ASSERT_EQ(reconstructed->getMemory()->getFlags() & IMemoryHeap::READ_ONLY,  0);
78     const uint8_t* p =
79             reinterpret_cast<const uint8_t*>(reconstructed->unsecurePointer());
80     EXPECT_EQ(6, p[0]);
81     EXPECT_EQ(5, p[1]);
82     EXPECT_EQ(3, p[2]);
83 }
84 
TEST(ShmemTest,ConversionReadOnly)85 TEST(ShmemTest, ConversionReadOnly) {
86     sp<IMemory> reconstructed;
87     {
88         SharedFileRegion shmem;
89         sp<IMemory> imem = makeIMemory({6, 5, 3}, false);
90         ASSERT_TRUE(convertIMemoryToSharedFileRegion(imem, &shmem));
91         ASSERT_EQ(3, shmem.size);
92         ASSERT_GE(shmem.fd.get(), 0);
93         ASSERT_FALSE(shmem.writeable);
94         ASSERT_TRUE(convertSharedFileRegionToIMemory(shmem, &reconstructed));
95     }
96     ASSERT_EQ(3, reconstructed->size());
97     ASSERT_NE(reconstructed->getMemory()->getFlags() & IMemoryHeap::READ_ONLY,  0);
98     const uint8_t* p =
99             reinterpret_cast<const uint8_t*>(reconstructed->unsecurePointer());
100     EXPECT_EQ(6, p[0]);
101     EXPECT_EQ(5, p[1]);
102     EXPECT_EQ(3, p[2]);
103 }
104 
TEST(ShmemTest,NullConversion)105 TEST(ShmemTest, NullConversion) {
106     sp<IMemory> reconstructed;
107     {
108         std::optional<SharedFileRegion> shmem;
109         sp<IMemory> imem;
110         ASSERT_TRUE(convertNullableIMemoryToSharedFileRegion(imem, &shmem));
111         ASSERT_FALSE(shmem.has_value());
112         ASSERT_TRUE(convertNullableSharedFileRegionToIMemory(shmem, &reconstructed));
113     }
114     ASSERT_EQ(nullptr, reconstructed);
115 }
116 
117 }  // namespace
118 }  // namespace media
119 }  // namespace android
120