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

Commit 513ca331 authored by Xin Li's avatar Xin Li
Browse files

Merge Android 12

Bug: 202323961
Merged-In: I6c3beb288ae8733ef65723d8ae5bc820a65f17c2
Change-Id: I1f1c2bf1a8e11d4cb590a0df4695caa3e16d4ba5
parents 79de5149 3afebabf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -448,6 +448,7 @@ cc_test {

    srcs: [
        "devices_test.cpp",
        "epoll_test.cpp",
        "firmware_handler_test.cpp",
        "init_test.cpp",
        "keychords_test.cpp",
+7 −5
Original line number Diff line number Diff line
@@ -38,11 +38,12 @@ Result<void> Epoll::Open() {
    return {};
}

Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
Result<void> Epoll::RegisterHandler(int fd, Handler handler, uint32_t events) {
    if (!events) {
        return Error() << "Must specify events";
    }
    auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler));
    auto sp = std::make_shared<decltype(handler)>(std::move(handler));
    auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));
    if (!inserted) {
        return Error() << "Cannot specify two epoll handlers for a given FD";
    }
@@ -69,7 +70,7 @@ Result<void> Epoll::UnregisterHandler(int fd) {
    return {};
}

Result<std::vector<std::function<void()>*>> Epoll::Wait(
Result<std::vector<std::shared_ptr<Epoll::Handler>>> Epoll::Wait(
        std::optional<std::chrono::milliseconds> timeout) {
    int timeout_ms = -1;
    if (timeout && timeout->count() < INT_MAX) {
@@ -81,9 +82,10 @@ Result<std::vector<std::function<void()>*>> Epoll::Wait(
    if (num_events == -1) {
        return ErrnoError() << "epoll_wait failed";
    }
    std::vector<std::function<void()>*> pending_functions;
    std::vector<std::shared_ptr<Handler>> pending_functions;
    for (int i = 0; i < num_events; ++i) {
        pending_functions.emplace_back(reinterpret_cast<std::function<void()>*>(ev[i].data.ptr));
        auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
        pending_functions.emplace_back(std::move(sp));
    }

    return pending_functions;
+6 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <chrono>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <vector>

@@ -36,15 +37,17 @@ class Epoll {
  public:
    Epoll();

    typedef std::function<void()> Handler;

    Result<void> Open();
    Result<void> RegisterHandler(int fd, std::function<void()> handler, uint32_t events = EPOLLIN);
    Result<void> RegisterHandler(int fd, Handler handler, uint32_t events = EPOLLIN);
    Result<void> UnregisterHandler(int fd);
    Result<std::vector<std::function<void()>*>> Wait(
    Result<std::vector<std::shared_ptr<Handler>>> Wait(
            std::optional<std::chrono::milliseconds> timeout);

  private:
    android::base::unique_fd epoll_fd_;
    std::map<int, std::function<void()>> epoll_handlers_;
    std::map<int, std::shared_ptr<Handler>> epoll_handlers_;
};

}  // namespace init

init/epoll_test.cpp

0 → 100644
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 "epoll.h"

#include <sys/unistd.h>

#include <unordered_set>

#include <android-base/file.h>
#include <gtest/gtest.h>

namespace android {
namespace init {

std::unordered_set<void*> sValidObjects;

class CatchDtor final {
  public:
    CatchDtor() { sValidObjects.emplace(this); }
    CatchDtor(const CatchDtor&) { sValidObjects.emplace(this); }
    ~CatchDtor() {
        auto iter = sValidObjects.find(this);
        if (iter != sValidObjects.end()) {
            sValidObjects.erase(iter);
        }
    }
};

TEST(epoll, UnregisterHandler) {
    Epoll epoll;
    ASSERT_RESULT_OK(epoll.Open());

    int fds[2];
    ASSERT_EQ(pipe(fds), 0);

    CatchDtor catch_dtor;
    bool handler_invoked;
    auto handler = [&, catch_dtor]() -> void {
        auto result = epoll.UnregisterHandler(fds[0]);
        ASSERT_EQ(result.ok(), !handler_invoked);
        handler_invoked = true;
        ASSERT_NE(sValidObjects.find((void*)&catch_dtor), sValidObjects.end());
    };

    epoll.RegisterHandler(fds[0], std::move(handler));

    uint8_t byte = 0xee;
    ASSERT_TRUE(android::base::WriteFully(fds[1], &byte, sizeof(byte)));

    auto results = epoll.Wait({});
    ASSERT_RESULT_OK(results);
    ASSERT_EQ(results->size(), size_t(1));

    for (const auto& function : *results) {
        (*function)();
        (*function)();
    }
    ASSERT_TRUE(handler_invoked);
}

}  // namespace init
}  // namespace android
+37 −77
Original line number Diff line number Diff line
@@ -199,100 +199,60 @@ status_t String16::setTo(const char16_t* other, size_t len)
    return NO_MEMORY;
}

status_t String16::append(const String16& other)
{
    const size_t myLen = size();
    const size_t otherLen = other.size();
    if (myLen == 0) {
        setTo(other);
        return OK;
    } else if (otherLen == 0) {
        return OK;
status_t String16::append(const String16& other) {
    return append(other.string(), other.size());
}

    if (myLen >= SIZE_MAX / sizeof(char16_t) - otherLen) {
        android_errorWriteLog(0x534e4554, "73826242");
        abort();
    }
status_t String16::append(const char16_t* chrs, size_t otherLen) {
    const size_t myLen = size();

    SharedBuffer* buf =
            static_cast<SharedBuffer*>(editResize((myLen + otherLen + 1) * sizeof(char16_t)));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
        mString = str;
        return OK;
    }
    return NO_MEMORY;
}
    if (myLen == 0) return setTo(chrs, otherLen);

status_t String16::append(const char16_t* chrs, size_t otherLen)
{
    const size_t myLen = size();
    if (myLen == 0) {
        setTo(chrs, otherLen);
        return OK;
    } else if (otherLen == 0) {
        return OK;
    }
    if (otherLen == 0) return OK;

    if (myLen >= SIZE_MAX / sizeof(char16_t) - otherLen) {
        android_errorWriteLog(0x534e4554, "73826242");
        abort();
    }
    size_t size = myLen;
    if (__builtin_add_overflow(size, otherLen, &size) ||
        __builtin_add_overflow(size, 1, &size) ||
        __builtin_mul_overflow(size, sizeof(char16_t), &size)) return NO_MEMORY;

    SharedBuffer* buf =
            static_cast<SharedBuffer*>(editResize((myLen + otherLen + 1) * sizeof(char16_t)));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
    SharedBuffer* buf = static_cast<SharedBuffer*>(editResize(size));
    if (!buf) return NO_MEMORY;

    char16_t* str = static_cast<char16_t*>(buf->data());
    memcpy(str + myLen, chrs, otherLen * sizeof(char16_t));
    str[myLen + otherLen] = 0;
    mString = str;
    return OK;
}
    return NO_MEMORY;
}

status_t String16::insert(size_t pos, const char16_t* chrs)
{
status_t String16::insert(size_t pos, const char16_t* chrs) {
    return insert(pos, chrs, strlen16(chrs));
}

status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
{
status_t String16::insert(size_t pos, const char16_t* chrs, size_t otherLen) {
    const size_t myLen = size();
    if (myLen == 0) {
        return setTo(chrs, len);
        return OK;
    } else if (len == 0) {
        return OK;
    }

    if (myLen == 0) return setTo(chrs, otherLen);

    if (otherLen == 0) return OK;

    if (pos > myLen) pos = myLen;

    #if 0
    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
           String8(*this).string(), pos,
           len, myLen, String8(chrs, len).string());
    #endif
    size_t size = myLen;
    if (__builtin_add_overflow(size, otherLen, &size) ||
        __builtin_add_overflow(size, 1, &size) ||
        __builtin_mul_overflow(size, sizeof(char16_t), &size)) return NO_MEMORY;

    SharedBuffer* buf =
            static_cast<SharedBuffer*>(editResize((myLen + len + 1) * sizeof(char16_t)));
    if (buf) {
        char16_t* str = (char16_t*)buf->data();
        if (pos < myLen) {
            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
        }
        memcpy(str+pos, chrs, len*sizeof(char16_t));
        str[myLen+len] = 0;
    SharedBuffer* buf = static_cast<SharedBuffer*>(editResize(size));
    if (!buf) return NO_MEMORY;

    char16_t* str = static_cast<char16_t*>(buf->data());
    if (pos < myLen) memmove(str + pos + otherLen, str + pos, (myLen - pos) * sizeof(char16_t));
    memcpy(str + pos, chrs, otherLen * sizeof(char16_t));
    str[myLen + otherLen] = 0;
    mString = str;
        #if 0
        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
        #endif
    return OK;
}
    return NO_MEMORY;
}

ssize_t String16::findFirst(char16_t c) const
{
Loading