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

Commit ad147db0 authored by Michael Hoisie's avatar Michael Hoisie Committed by Automerger Merge Worker
Browse files

Merge "Add support for ashmem-host for host Windows" into main am: a79e3d4c

parents 50d1b2c8 a79e3d4c
Loading
Loading
Loading
Loading
+20 −17
Original line number Diff line number Diff line
@@ -155,23 +155,18 @@ cc_library {
                "fs_config.cpp",
            ],
        },
        not_windows: {
            srcs: libcutils_nonwindows_sources + [
                "ashmem-host.cpp",
        host: {
            srcs: [
                "trace-host.cpp",
                "ashmem-host.cpp",
            ],
        },
        not_windows: {
            srcs: libcutils_nonwindows_sources,
        },
        windows: {
            host_ldlibs: ["-lws2_32"],

            srcs: [
                "trace-host.cpp",
            ],

            enabled: true,
            cflags: [
                "-D_GNU_SOURCE",
            ],
            host_ldlibs: ["-lws2_32"],
        },
        android: {
            sanitize: {
@@ -240,6 +235,7 @@ cc_library {
cc_defaults {
    name: "libcutils_test_default",
    srcs: [
        "ashmem_base_test.cpp",
        "native_handle_test.cpp",
        "properties_test.cpp",
        "sockets_test.cpp",
@@ -298,20 +294,26 @@ cc_test {
cc_defaults {
    name: "libcutils_test_static_defaults",
    defaults: ["libcutils_test_default"],
    static_libs: [
        "libc",
        "libcgrouprc_format",
    ] + test_libraries + always_static_test_libraries,
    stl: "libc++_static",
    require_root: true,

    target: {
        android: {
            static_executable: true,
            static_libs: [
                "libcgrouprc_format",
            ] + test_libraries + always_static_test_libraries,
        },
        not_windows: {
            static_libs: test_libraries + always_static_test_libraries,
        },
        windows: {
            static_libs: [
                "libbase",
                "libcutils",
                "libcutils_sockets",
            ],
            host_ldlibs: ["-lws2_32"],

            enabled: true,
        },
    },
@@ -319,6 +321,7 @@ cc_defaults {

cc_test {
    name: "libcutils_test_static",
    host_supported: true,
    test_suites: ["device-tests"],
    defaults: ["libcutils_test_static_defaults"],
}
+35 −20
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@
#include <cutils/ashmem.h>

/*
 * Implementation of the user-space ashmem API for the simulator, which lacks
 * an ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version.
 * Implementation of the user-space ashmem API for the simulator, which lacks an
 * ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version.  A
 * disk-backed temp file is the best option that is consistently supported
 * across all host platforms.
 */

#include <android-base/unique_fd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
@@ -31,8 +34,10 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <utils/Compat.h>
#include <memory>

using android::base::unique_fd;

static bool ashmem_validate_stat(int fd, struct stat* buf) {
    int result = fstat(fd, buf);
@@ -40,15 +45,20 @@ static bool ashmem_validate_stat(int fd, struct stat* buf) {
        return false;
    }

    /*
     * Check if this is an "ashmem" region.
     * TODO: This is very hacky, and can easily break.
     * We need some reliable indicator.
     */
    if (!(buf->st_nlink == 0 && S_ISREG(buf->st_mode))) {
    // Check if this is an ashmem region. Since there's no such thing on the host,
    // we can't actually implement that. Check that it's at least a regular file.
    if (!S_ISREG(buf->st_mode)) {
        errno = ENOTTY;
        return false;
    }
    // In Win32, unlike Unix, the temp file is not unlinked immediately after
    // creation.
#if !defined(_WIN32)
    if (buf->st_nlink != 0) {
        errno = ENOTTY;
        return false;
    }
#endif
    return true;
}

@@ -58,19 +68,24 @@ int ashmem_valid(int fd) {
}

int ashmem_create_region(const char* /*ignored*/, size_t size) {
    char pattern[PATH_MAX];
    snprintf(pattern, sizeof(pattern), "/tmp/android-ashmem-%d-XXXXXXXXX", getpid());
    int fd = mkstemp(pattern);
    if (fd == -1) return -1;

    unlink(pattern);
    // Files returned by tmpfile are automatically removed.
    std::unique_ptr<FILE, decltype(&fclose)> tmp(tmpfile(), &fclose);

    if (TEMP_FAILURE_RETRY(ftruncate(fd, size)) == -1) {
      close(fd);
    if (!tmp) {
        return -1;
    }

    return fd;
    int fd = fileno(tmp.get());
    if (fd == -1) {
        return -1;
    }
    unique_fd dupfd = unique_fd(dup(fd));
    if (dupfd == -1) {
        return -1;
    }
    if (TEMP_FAILURE_RETRY(ftruncate(dupfd, size)) == -1) {
        return -1;
    }
    return dupfd.release();
}

int ashmem_set_prot_region(int /*fd*/, int /*prot*/) {
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <unistd.h>

#include <android-base/mapped_file.h>
#include <android-base/unique_fd.h>
#include <cutils/ashmem.h>

/*
 * Tests in AshmemBaseTest are designed to run on Android as well as host
 * platforms (Linux, Mac, Windows).
 */

#if defined(_WIN32)
static inline size_t getpagesize() {
    return 4096;
}
#endif

using android::base::unique_fd;

TEST(AshmemBaseTest, BasicTest) {
    const size_t size = getpagesize();
    std::vector<uint8_t> data(size);
    std::generate(data.begin(), data.end(), [n = 0]() mutable { return n++ & 0xFF; });

    unique_fd fd = unique_fd(ashmem_create_region(nullptr, size));
    ASSERT_TRUE(fd >= 0);
    ASSERT_TRUE(ashmem_valid(fd));
    ASSERT_EQ(size, static_cast<size_t>(ashmem_get_size_region(fd)));

    std::unique_ptr<android::base::MappedFile> mapped =
            android::base::MappedFile::FromFd(fd, 0, size, PROT_READ | PROT_WRITE);
    EXPECT_TRUE(mapped.get() != nullptr);
    void* region1 = mapped->data();
    EXPECT_TRUE(region1 != nullptr);

    memcpy(region1, data.data(), size);
    ASSERT_EQ(0, memcmp(region1, data.data(), size));

    std::unique_ptr<android::base::MappedFile> mapped2 =
            android::base::MappedFile::FromFd(fd, 0, size, PROT_READ | PROT_WRITE);
    EXPECT_TRUE(mapped2.get() != nullptr);
    void* region2 = mapped2->data();
    EXPECT_TRUE(region2 != nullptr);
    ASSERT_EQ(0, memcmp(region2, data.data(), size));
}
+0 −22
Original line number Diff line number Diff line
@@ -69,28 +69,6 @@ void FillData(std::vector<uint8_t>& data) {
    }
}

TEST(AshmemTest, BasicTest) {
    const size_t size = getpagesize();
    std::vector<uint8_t> data(size);
    FillData(data);

    unique_fd fd;
    ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));

    void* region1 = nullptr;
    ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ | PROT_WRITE, &region1));

    memcpy(region1, data.data(), size);
    ASSERT_EQ(0, memcmp(region1, data.data(), size));

    EXPECT_EQ(0, munmap(region1, size));

    void *region2;
    ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ, &region2));
    ASSERT_EQ(0, memcmp(region2, data.data(), size));
    EXPECT_EQ(0, munmap(region2, size));
}

TEST(AshmemTest, ForkTest) {
    const size_t size = getpagesize();
    std::vector<uint8_t> data(size);
+0 −2
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@
// should be the case for loopback communication, but is not guaranteed.

#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>

#include <cutils/sockets.h>