diff --git a/init/Android.bp b/init/Android.bp
index a3083c1..517847c 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -170,6 +170,7 @@
     srcs: [
         "devices_test.cpp",
         "init_test.cpp",
+        "keychords_test.cpp",
         "persistent_properties_test.cpp",
         "property_service_test.cpp",
         "property_type_test.cpp",
diff --git a/init/keychords_test.cpp b/init/keychords_test.cpp
new file mode 100644
index 0000000..c8c47a8
--- /dev/null
+++ b/init/keychords_test.cpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2018 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 "keychords.h"
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <chrono>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <gtest/gtest.h>
+
+#include "epoll.h"
+
+using namespace std::chrono_literals;
+
+namespace android {
+namespace init {
+
+namespace {
+
+// This class is used to inject keys.
+class EventHandler {
+  public:
+    EventHandler();
+    EventHandler(const EventHandler&) = delete;
+    EventHandler(EventHandler&&);
+    EventHandler& operator=(const EventHandler&) = delete;
+    EventHandler& operator=(EventHandler&&);
+    ~EventHandler() noexcept;
+
+    bool init();
+
+    bool send(struct input_event& e);
+    bool send(uint16_t type, uint16_t code, uint16_t value);
+    bool send(uint16_t code, bool value);
+
+  private:
+    int fd_;
+};
+
+EventHandler::EventHandler() : fd_(-1) {}
+
+EventHandler::EventHandler(EventHandler&& rval) : fd_(rval.fd_) {
+    rval.fd_ = -1;
+}
+
+EventHandler& EventHandler::operator=(EventHandler&& rval) {
+    fd_ = rval.fd_;
+    rval.fd_ = -1;
+    return *this;
+}
+
+EventHandler::~EventHandler() {
+    if (fd_ == -1) return;
+    ::ioctl(fd_, UI_DEV_DESTROY);
+    ::close(fd_);
+}
+
+bool EventHandler::init() {
+    if (fd_ != -1) return true;
+    auto fd = TEMP_FAILURE_RETRY(::open("/dev/uinput", O_WRONLY | O_NONBLOCK | O_CLOEXEC));
+    if (fd == -1) return false;
+    if (::ioctl(fd, UI_SET_EVBIT, EV_KEY) == -1) {
+        ::close(fd);
+        return false;
+    }
+
+    static const struct uinput_user_dev u = {
+        .name = "com.google.android.init.test",
+        .id.bustype = BUS_VIRTUAL,
+        .id.vendor = 0x1AE0,   // Google
+        .id.product = 0x494E,  // IN
+        .id.version = 1,
+    };
+    if (TEMP_FAILURE_RETRY(::write(fd, &u, sizeof(u))) != sizeof(u)) {
+        ::close(fd);
+        return false;
+    }
+
+    // all keys
+    for (uint16_t i = 0; i < KEY_MAX; ++i) {
+        if (::ioctl(fd, UI_SET_KEYBIT, i) == -1) {
+            ::close(fd);
+            return false;
+        }
+    }
+    if (::ioctl(fd, UI_DEV_CREATE) == -1) {
+        ::close(fd);
+        return false;
+    }
+    fd_ = fd;
+    return true;
+}
+
+bool EventHandler::send(struct input_event& e) {
+    gettimeofday(&e.time, nullptr);
+    return TEMP_FAILURE_RETRY(::write(fd_, &e, sizeof(e))) == sizeof(e);
+}
+
+bool EventHandler::send(uint16_t type, uint16_t code, uint16_t value) {
+    struct input_event e = {.type = type, .code = code, .value = value};
+    return send(e);
+}
+
+bool EventHandler::send(uint16_t code, bool value) {
+    return (code < KEY_MAX) && init() && send(EV_KEY, code, value) && send(EV_SYN, SYN_REPORT, 0);
+}
+
+std::string InitFds(const char* prefix, pid_t pid = getpid()) {
+    std::string ret;
+
+    std::string init_fds("/proc/");
+    init_fds += std::to_string(pid) + "/fd";
+    std::unique_ptr<DIR, decltype(&closedir)> fds(opendir(init_fds.c_str()), closedir);
+    if (!fds) return ret;
+
+    dirent* entry;
+    while ((entry = readdir(fds.get()))) {
+        if (entry->d_name[0] == '.') continue;
+        std::string devname = init_fds + '/' + entry->d_name;
+        char buf[256];
+        auto retval = readlink(devname.c_str(), buf, sizeof(buf) - 1);
+        if ((retval < 0) || (size_t(retval) >= (sizeof(buf) - 1))) continue;
+        buf[retval] = '\0';
+        if (!android::base::StartsWith(buf, prefix)) continue;
+        if (ret.size() != 0) ret += ",";
+        ret += buf;
+    }
+    return ret;
+}
+
+std::string InitInputFds() {
+    return InitFds("/dev/input/");
+}
+
+std::string InitInotifyFds() {
+    return InitFds("anon_inode:inotify");
+}
+
+// NB: caller (this series of tests, or conversely the service parser in init)
+// is responsible for validation, sorting and uniqueness of the chords, so no
+// fuzzing is advised.
+
+const std::vector<int> escape_chord = {KEY_ESC};
+const std::vector<int> triple1_chord = {KEY_BACKSPACE, KEY_VOLUMEDOWN, KEY_VOLUMEUP};
+const std::vector<int> triple2_chord = {KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_BACK};
+
+const std::vector<const std::vector<int>> empty_chords;
+const std::vector<const std::vector<int>> chords = {
+    escape_chord,
+    triple1_chord,
+    triple2_chord,
+};
+
+class TestFrame {
+  public:
+    TestFrame(const std::vector<const std::vector<int>>& chords, EventHandler* ev = nullptr);
+
+    void RelaxForMs(std::chrono::milliseconds wait = 1ms);
+
+    void SetChord(int key, bool value = true);
+    void SetChords(const std::vector<int>& chord, bool value = true);
+    void ClrChord(int key);
+    void ClrChords(const std::vector<int>& chord);
+
+    bool IsOnlyChord(const std::vector<int>& chord) const;
+    bool IsNoChord() const;
+    bool IsChord(const std::vector<int>& chord) const;
+    void WaitForChord(const std::vector<int>& chord);
+
+    std::string Format() const;
+
+  private:
+    static std::string Format(const std::vector<const std::vector<int>>& chords);
+
+    Epoll epoll_;
+    Keychords keychords_;
+    std::vector<const std::vector<int>> keycodes_;
+    EventHandler* ev_;
+};
+
+TestFrame::TestFrame(const std::vector<const std::vector<int>>& chords, EventHandler* ev)
+    : ev_(ev) {
+    if (!epoll_.Open()) return;
+    for (const auto& keycodes : chords) keychords_.Register(keycodes);
+    keychords_.Start(&epoll_, [this](const std::vector<int>& keycodes) {
+        this->keycodes_.emplace_back(keycodes);
+    });
+}
+
+void TestFrame::RelaxForMs(std::chrono::milliseconds wait) {
+    epoll_.Wait(wait);
+}
+
+void TestFrame::SetChord(int key, bool value) {
+    ASSERT_TRUE(!!ev_);
+    RelaxForMs();
+    EXPECT_TRUE(ev_->send(key, value));
+}
+
+void TestFrame::SetChords(const std::vector<int>& chord, bool value) {
+    ASSERT_TRUE(!!ev_);
+    for (auto& key : chord) SetChord(key, value);
+    RelaxForMs();
+}
+
+void TestFrame::ClrChord(int key) {
+    ASSERT_TRUE(!!ev_);
+    SetChord(key, false);
+}
+
+void TestFrame::ClrChords(const std::vector<int>& chord) {
+    ASSERT_TRUE(!!ev_);
+    SetChords(chord, false);
+}
+
+bool TestFrame::IsOnlyChord(const std::vector<int>& chord) const {
+    auto ret = false;
+    for (const auto& keycode : keycodes_) {
+        if (keycode != chord) return false;
+        ret = true;
+    }
+    return ret;
+}
+
+bool TestFrame::IsNoChord() const {
+    return keycodes_.empty();
+}
+
+bool TestFrame::IsChord(const std::vector<int>& chord) const {
+    for (const auto& keycode : keycodes_) {
+        if (keycode == chord) return true;
+    }
+    return false;
+}
+
+void TestFrame::WaitForChord(const std::vector<int>& chord) {
+    for (int retry = 1000; retry && !IsChord(chord); --retry) RelaxForMs();
+}
+
+std::string TestFrame::Format(const std::vector<const std::vector<int>>& chords) {
+    std::string ret("{");
+    if (!chords.empty()) {
+        ret += android::base::Join(chords.front(), ' ');
+        for (auto it = std::next(chords.begin()); it != chords.end(); ++it) {
+            ret += ',';
+            ret += android::base::Join(*it, ' ');
+        }
+    }
+    return ret + '}';
+}
+
+std::string TestFrame::Format() const {
+    return Format(keycodes_);
+}
+
+}  // namespace
+
+TEST(keychords, not_instantiated) {
+    TestFrame test_frame(empty_chords);
+    EXPECT_TRUE(InitInotifyFds().size() == 0);
+}
+
+TEST(keychords, instantiated) {
+    // Test if a valid set of chords results in proper instantiation of the
+    // underlying mechanisms for /dev/input/ attachment.
+    TestFrame test_frame(chords);
+    EXPECT_TRUE(InitInotifyFds().size() != 0);
+}
+
+TEST(keychords, init_inotify) {
+    std::string before(InitInputFds());
+
+    TestFrame test_frame(chords);
+
+    EventHandler ev;
+    EXPECT_TRUE(ev.init());
+
+    for (int retry = 1000; retry && before == InitInputFds(); --retry) test_frame.RelaxForMs();
+    std::string after(InitInputFds());
+    EXPECT_NE(before, after);
+}
+
+TEST(keychords, key) {
+    EventHandler ev;
+    EXPECT_TRUE(ev.init());
+    TestFrame test_frame(chords, &ev);
+
+    test_frame.SetChords(escape_chord);
+    test_frame.WaitForChord(escape_chord);
+    test_frame.ClrChords(escape_chord);
+    EXPECT_TRUE(test_frame.IsOnlyChord(escape_chord))
+        << "expected only " << android::base::Join(escape_chord, ' ') << " got "
+        << test_frame.Format();
+}
+
+TEST(keychords, keys_in_series) {
+    EventHandler ev;
+    EXPECT_TRUE(ev.init());
+    TestFrame test_frame(chords, &ev);
+
+    for (auto& key : triple1_chord) {
+        test_frame.SetChord(key);
+        test_frame.ClrChord(key);
+    }
+    test_frame.WaitForChord(triple1_chord);
+    EXPECT_TRUE(test_frame.IsNoChord()) << "expected nothing got " << test_frame.Format();
+}
+
+TEST(keychords, keys_in_parallel) {
+    EventHandler ev;
+    EXPECT_TRUE(ev.init());
+    TestFrame test_frame(chords, &ev);
+
+    test_frame.SetChords(triple2_chord);
+    test_frame.WaitForChord(triple2_chord);
+    test_frame.ClrChords(triple2_chord);
+    EXPECT_TRUE(test_frame.IsOnlyChord(triple2_chord))
+        << "expected only " << android::base::Join(triple2_chord, ' ') << " got "
+        << test_frame.Format();
+}
+
+}  // namespace init
+}  // namespace android
