Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc700a03 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Add support for read-only SharedFileRegion

A receiver of a SharedFileRegion needs to know whether it is allowed
to write into it. Added a flag in the AIDL file to indicate that and
made this compatible with the READ_ONLY flag of IMemoryHeap.

Test: atest shmemTest
Change-Id: I3f26a36e152c2e9bf3aac4ff7f0067f9242b565b
parent d5aa6164
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -49,8 +49,10 @@ bool convertSharedFileRegionToIMemory(const SharedFileRegion& shmem,
        return false;
    }

    uint32_t flags = !shmem.writeable ? IMemoryHeap::READ_ONLY : 0;

    const sp<MemoryHeapBase> heap =
            new MemoryHeapBase(shmem.fd.get(), heapSize, 0, heapStartOffset);
            new MemoryHeapBase(shmem.fd.get(), heapSize, flags, heapStartOffset);
    *result = sp<MemoryBase>::make(heap,
                                   shmem.offset - heapStartOffset,
                                   shmem.size);
@@ -89,6 +91,7 @@ bool convertIMemoryToSharedFileRegion(const sp<IMemory>& mem,
        result->fd.reset(base::unique_fd(fd));
        result->size = size;
        result->offset = heap->getOffset() + offset;
        result->writeable = (heap->getFlags() & IMemoryHeap::READ_ONLY) == 0;
    }
    return true;
}
+25 −2
Original line number Diff line number Diff line
@@ -44,10 +44,11 @@ SharedFileRegion makeInvalidSharedFileRegion(int64_t offset, int64_t size) {
    return shmem;
}

sp<IMemory> makeIMemory(const std::vector<uint8_t>& content) {
sp<IMemory> makeIMemory(const std::vector<uint8_t>& content, bool writeable = true) {
    constexpr size_t kOffset = 19;

    sp<MemoryHeapBase> heap = new MemoryHeapBase(content.size());
    sp<MemoryHeapBase> heap = new MemoryHeapBase(content.size(),
                                                 !writeable ? IMemoryHeap::READ_ONLY : 0);
    sp<IMemory> result = sp<MemoryBase>::make(heap, kOffset, content.size());
    memcpy(result->unsecurePointer(), content.data(), content.size());
    return result;
@@ -69,9 +70,31 @@ TEST(ShmemTest, Conversion) {
        ASSERT_TRUE(convertIMemoryToSharedFileRegion(imem, &shmem));
        ASSERT_EQ(3, shmem.size);
        ASSERT_GE(shmem.fd.get(), 0);
        ASSERT_TRUE(shmem.writeable);
        ASSERT_TRUE(convertSharedFileRegionToIMemory(shmem, &reconstructed));
    }
    ASSERT_EQ(3, reconstructed->size());
    ASSERT_EQ(reconstructed->getMemory()->getFlags() & IMemoryHeap::READ_ONLY,  0);
    const uint8_t* p =
            reinterpret_cast<const uint8_t*>(reconstructed->unsecurePointer());
    EXPECT_EQ(6, p[0]);
    EXPECT_EQ(5, p[1]);
    EXPECT_EQ(3, p[2]);
}

TEST(ShmemTest, ConversionReadOnly) {
    sp<IMemory> reconstructed;
    {
        SharedFileRegion shmem;
        sp<IMemory> imem = makeIMemory({6, 5, 3}, false);
        ASSERT_TRUE(convertIMemoryToSharedFileRegion(imem, &shmem));
        ASSERT_EQ(3, shmem.size);
        ASSERT_GE(shmem.fd.get(), 0);
        ASSERT_FALSE(shmem.writeable);
        ASSERT_TRUE(convertSharedFileRegionToIMemory(shmem, &reconstructed));
    }
    ASSERT_EQ(3, reconstructed->size());
    ASSERT_NE(reconstructed->getMemory()->getFlags() & IMemoryHeap::READ_ONLY,  0);
    const uint8_t* p =
            reinterpret_cast<const uint8_t*>(reconstructed->unsecurePointer());
    EXPECT_EQ(6, p[0]);
+2 −0
Original line number Diff line number Diff line
@@ -34,4 +34,6 @@ parcelable SharedFileRegion {
    long offset;
    /** Size, in bytes of the memory region. Must be non-negative. */
    long size;
    /** Whether the region is writeable. */
    boolean writeable;
}