diff --git a/init/keychords.cpp b/init/keychords.cpp
index 1a8f2ae..9aa8b2a 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -37,95 +37,85 @@
 namespace android {
 namespace init {
 
-namespace {
+Keychords::Keychords() : epoll_(nullptr), count_(0), inotify_fd_(-1) {}
 
-int keychords_count;
-Epoll* epoll;
-std::function<void(int)> handle_keychord;
-
-struct KeychordEntry {
-    const std::vector<int> keycodes;
-    bool notified;
-    int id;
-
-    KeychordEntry(const std::vector<int>& keycodes, int id)
-        : keycodes(keycodes), notified(false), id(id) {}
-};
-
-std::vector<KeychordEntry> keychord_entries;
-
-// Bit management
-class KeychordMask {
-  private:
-    typedef unsigned int mask_t;
-    std::vector<mask_t> bits;
-    static constexpr size_t bits_per_byte = 8;
-
-  public:
-    explicit KeychordMask(size_t bit = 0) : bits((bit + sizeof(mask_t) - 1) / sizeof(mask_t), 0) {}
-
-    void SetBit(size_t bit, bool value = true) {
-        auto idx = bit / (bits_per_byte * sizeof(mask_t));
-        if (idx >= bits.size()) return;
-        if (value) {
-            bits[idx] |= mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t)));
-        } else {
-            bits[idx] &= ~(mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t))));
-        }
+Keychords::~Keychords() noexcept {
+    if (inotify_fd_ >= 0) {
+        epoll_->UnregisterHandler(inotify_fd_);
+        ::close(inotify_fd_);
     }
+    while (!registration_.empty()) GeteventCloseDevice(registration_.begin()->first);
+}
 
-    bool GetBit(size_t bit) const {
-        auto idx = bit / (bits_per_byte * sizeof(mask_t));
-        return bits[idx] & (mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t))));
+Keychords::Mask::Mask(size_t bit) : bits_((bit + sizeof(mask_t) - 1) / sizeof(mask_t), 0) {}
+
+void Keychords::Mask::SetBit(size_t bit, bool value) {
+    auto idx = bit / (kBitsPerByte * sizeof(mask_t));
+    if (idx >= bits_.size()) return;
+    if (value) {
+        bits_[idx] |= mask_t(1) << (bit % (kBitsPerByte * sizeof(mask_t)));
+    } else {
+        bits_[idx] &= ~(mask_t(1) << (bit % (kBitsPerByte * sizeof(mask_t))));
     }
+}
 
-    size_t bytesize() const { return bits.size() * sizeof(mask_t); }
-    void* data() { return bits.data(); }
-    size_t size() const { return bits.size() * sizeof(mask_t) * bits_per_byte; }
-    void resize(size_t bit) {
-        auto idx = bit / (bits_per_byte * sizeof(mask_t));
-        if (idx >= bits.size()) {
-            bits.resize(idx + 1, 0);
-        }
+bool Keychords::Mask::GetBit(size_t bit) const {
+    auto idx = bit / (kBitsPerByte * sizeof(mask_t));
+    return bits_[idx] & (mask_t(1) << (bit % (kBitsPerByte * sizeof(mask_t))));
+}
+
+size_t Keychords::Mask::bytesize() const {
+    return bits_.size() * sizeof(mask_t);
+}
+
+void* Keychords::Mask::data() {
+    return bits_.data();
+}
+
+size_t Keychords::Mask::size() const {
+    return bits_.size() * sizeof(mask_t) * kBitsPerByte;
+}
+
+void Keychords::Mask::resize(size_t bit) {
+    auto idx = bit / (kBitsPerByte * sizeof(mask_t));
+    if (idx >= bits_.size()) {
+        bits_.resize(idx + 1, 0);
     }
+}
 
-    operator bool() const {
-        for (size_t i = 0; i < bits.size(); ++i) {
-            if (bits[i]) return true;
-        }
-        return false;
+Keychords::Mask::operator bool() const {
+    for (size_t i = 0; i < bits_.size(); ++i) {
+        if (bits_[i]) return true;
     }
+    return false;
+}
 
-    KeychordMask operator&(const KeychordMask& rval) const {
-        auto len = std::min(bits.size(), rval.bits.size());
-        KeychordMask ret;
-        ret.bits.resize(len);
-        for (size_t i = 0; i < len; ++i) {
-            ret.bits[i] = bits[i] & rval.bits[i];
-        }
-        return ret;
+Keychords::Mask Keychords::Mask::operator&(const Keychords::Mask& rval) const {
+    auto len = std::min(bits_.size(), rval.bits_.size());
+    Keychords::Mask ret;
+    ret.bits_.resize(len);
+    for (size_t i = 0; i < len; ++i) {
+        ret.bits_[i] = bits_[i] & rval.bits_[i];
     }
+    return ret;
+}
 
-    void operator|=(const KeychordMask& rval) {
-        size_t len = rval.bits.size();
-        bits.resize(len);
-        for (size_t i = 0; i < len; ++i) {
-            bits[i] |= rval.bits[i];
-        }
+void Keychords::Mask::operator|=(const Keychords::Mask& rval) {
+    auto len = rval.bits_.size();
+    bits_.resize(len);
+    for (size_t i = 0; i < len; ++i) {
+        bits_[i] |= rval.bits_[i];
     }
-};
+}
 
-KeychordMask keychord_current;
+Keychords::Entry::Entry(const std::vector<int>& keycodes, int id)
+    : keycodes(keycodes), id(id), notified(false) {}
 
-constexpr char kDevicePath[] = "/dev/input";
-
-std::map<std::string, int> keychord_registration;
-
-void KeychordLambdaCheck() {
-    for (auto& e : keychord_entries) {
-        bool found = true;
+void Keychords::LambdaCheck() {
+    for (auto& e : entries_) {
+        auto found = true;
         for (auto& code : e.keycodes) {
-            if (!keychord_current.GetBit(code)) {
+            if (!current_.GetBit(code)) {
                 e.notified = false;
                 found = false;
                 break;
@@ -134,19 +124,19 @@
         if (!found) continue;
         if (e.notified) continue;
         e.notified = true;
-        handle_keychord(e.id);
+        handler_(e.id);
     }
 }
 
-void KeychordLambdaHandler(int fd) {
+void Keychords::LambdaHandler(int fd) {
     input_event event;
     auto res = TEMP_FAILURE_RETRY(::read(fd, &event, sizeof(event)));
     if ((res != sizeof(event)) || (event.type != EV_KEY)) return;
-    keychord_current.SetBit(event.code, event.value);
-    KeychordLambdaCheck();
+    current_.SetBit(event.code, event.value);
+    LambdaCheck();
 }
 
-bool KeychordGeteventEnable(int fd) {
+bool Keychords::GeteventEnable(int fd) {
     // Make sure it is an event channel, should pass this ioctl call
     int version;
     if (::ioctl(fd, EVIOCGVERSION, &version)) return false;
@@ -154,7 +144,7 @@
 #ifdef EVIOCSMASK
     static auto EviocsmaskSupported = true;
     if (EviocsmaskSupported) {
-        KeychordMask mask(EV_KEY);
+        Keychords::Mask mask(EV_KEY);
         mask.SetBit(EV_KEY);
         input_mask msg = {};
         msg.type = EV_SYN;
@@ -167,16 +157,16 @@
     }
 #endif
 
-    KeychordMask mask;
-    for (auto& e : keychord_entries) {
+    Keychords::Mask mask;
+    for (auto& e : entries_) {
         for (auto& code : e.keycodes) {
             mask.resize(code);
             mask.SetBit(code);
         }
     }
 
-    keychord_current.resize(mask.size());
-    KeychordMask available(mask.size());
+    current_.resize(mask.size());
+    Keychords::Mask available(mask.size());
     auto res = ::ioctl(fd, EVIOCGBIT(EV_KEY, available.bytesize()), available.data());
     if (res == -1) return false;
     if (!(available & mask)) return false;
@@ -191,45 +181,43 @@
     }
 #endif
 
-    KeychordMask set(mask.size());
+    Keychords::Mask set(mask.size());
     res = ::ioctl(fd, EVIOCGKEY(res), set.data());
     if (res > 0) {
-        keychord_current |= mask & available & set;
-        KeychordLambdaCheck();
+        current_ |= mask & available & set;
+        LambdaCheck();
     }
-    epoll->RegisterHandler(fd, [fd]() { KeychordLambdaHandler(fd); });
+    epoll_->RegisterHandler(fd, [this, fd]() { this->LambdaHandler(fd); });
     return true;
 }
 
-void GeteventOpenDevice(const std::string& device) {
-    if (keychord_registration.count(device)) return;
+void Keychords::GeteventOpenDevice(const std::string& device) {
+    if (registration_.count(device)) return;
     auto fd = TEMP_FAILURE_RETRY(::open(device.c_str(), O_RDWR | O_CLOEXEC));
     if (fd == -1) {
         PLOG(ERROR) << "Can not open " << device;
         return;
     }
-    if (!KeychordGeteventEnable(fd)) {
+    if (!GeteventEnable(fd)) {
         ::close(fd);
     } else {
-        keychord_registration.emplace(device, fd);
+        registration_.emplace(device, fd);
     }
 }
 
-void GeteventCloseDevice(const std::string& device) {
-    auto it = keychord_registration.find(device);
-    if (it == keychord_registration.end()) return;
+void Keychords::GeteventCloseDevice(const std::string& device) {
+    auto it = registration_.find(device);
+    if (it == registration_.end()) return;
     auto fd = (*it).second;
-    epoll->UnregisterHandler(fd);
-    keychord_registration.erase(it);
+    epoll_->UnregisterHandler(fd);
+    registration_.erase(it);
     ::close(fd);
 }
 
-int inotify_fd = -1;
+void Keychords::InotifyHandler() {
+    unsigned char buf[512];  // History shows 32-64 bytes typical
 
-void InotifyHandler() {
-    unsigned char buf[512];
-
-    auto res = TEMP_FAILURE_RETRY(::read(inotify_fd, buf, sizeof(buf)));
+    auto res = TEMP_FAILURE_RETRY(::read(inotify_fd_, buf, sizeof(buf)));
     if (res < 0) {
         PLOG(WARNING) << "could not get event";
         return;
@@ -255,14 +243,15 @@
     }
 }
 
-void GeteventOpenDevice() {
-    inotify_fd = ::inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
-    if (inotify_fd < 0) {
+void Keychords::GeteventOpenDevice() {
+    inotify_fd_ = ::inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+    if (inotify_fd_ < 0) {
         PLOG(WARNING) << "Could not instantiate inotify for " << kDevicePath;
-    } else if (::inotify_add_watch(inotify_fd, kDevicePath, IN_DELETE | IN_CREATE | IN_ONLYDIR) < 0) {
+    } else if (::inotify_add_watch(inotify_fd_, kDevicePath, IN_DELETE | IN_CREATE | IN_ONLYDIR) <
+               0) {
         PLOG(WARNING) << "Could not add watch for " << kDevicePath;
-        ::close(inotify_fd);
-        inotify_fd = -1;
+        ::close(inotify_fd_);
+        inotify_fd_ = -1;
     }
 
     std::unique_ptr<DIR, decltype(&closedir)> device(opendir(kDevicePath), closedir);
@@ -277,22 +266,22 @@
         }
     }
 
-    if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler);
+    if (inotify_fd_ >= 0) {
+        epoll_->RegisterHandler(inotify_fd_, [this]() { this->InotifyHandler(); });
+    }
 }
 
-}  // namespace
-
-int GetKeychordId(const std::vector<int>& keycodes) {
+int Keychords::GetId(const std::vector<int>& keycodes) {
     if (keycodes.empty()) return 0;
-    ++keychords_count;
-    keychord_entries.emplace_back(KeychordEntry(keycodes, keychords_count));
-    return keychords_count;
+    ++count_;
+    entries_.emplace_back(Entry(keycodes, count_));
+    return count_;
 }
 
-void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler) {
-    epoll = init_epoll;
-    handle_keychord = handler;
-    if (keychords_count) GeteventOpenDevice();
+void Keychords::Start(Epoll* epoll, std::function<void(int)> handler) {
+    epoll_ = epoll;
+    handler_ = handler;
+    if (count_) GeteventOpenDevice();
 }
 
 }  // namespace init
