<commit_before>#pragma once

#include "boost_defs.hpp"

#include "gcd_utility.hpp"
#include "grabbable_state_manager.hpp"
#include "grabber_client.hpp"
#include "hid_manager.hpp"
#include "logger.hpp"
#include "types.hpp"

namespace krbn {
class device_observer final {
public:
  device_observer(const device_observer&) = delete;

  device_observer(const grabber_client& grabber_client) : grabber_client_(grabber_client) {
    grabbable_state_manager_.grabbable_state_changed.connect([this](auto&& registry_entry_id,
                                                                    auto&& grabbable_state,
                                                                    auto&& ungrabbable_temporarily_reason,
                                                                    auto&& time_stamp) {
      grabber_client_.grabbable_state_changed(registry_entry_id,
                                              grabbable_state,
                                              ungrabbable_temporarily_reason,
                                              time_stamp);
    });

    hid_manager_.set_log_enabled(true);

    hid_manager_.device_detecting.connect([](auto&& device) {
      if (iokit_utility::is_karabiner_virtual_hid_device(device)) {
        return false;
      }
      return true;
    });

    hid_manager_.device_detected.connect([this](auto&& human_interface_device) {
      grabbable_state_manager_.update(human_interface_device.get_registry_entry_id(),
                                      grabbable_state::device_error,
                                      ungrabbable_temporarily_reason::none,
                                      mach_absolute_time());

      human_interface_device.device_observed.connect([this](auto&& human_interface_device) {
        if (auto state = grabbable_state_manager_.get_grabbable_state(human_interface_device.get_registry_entry_id())) {
          // Keep grabbable_state if the state is already changed by value_callback.
          if (state->first == grabbable_state::device_error) {
            grabbable_state_manager_.update(human_interface_device.get_registry_entry_id(),
                                            grabbable_state::grabbable,
                                            ungrabbable_temporarily_reason::none,
                                            mach_absolute_time());
          }
        }
      });
      human_interface_device.values_arrived.connect([this](auto&& human_interface_device,
                                                           auto&& event_queue) {
        grabbable_state_manager_.update(event_queue);
      });
      human_interface_device.observe();
    });

    hid_manager_.start({
        std::make_pair(hid_usage_page::generic_desktop, hid_usage::gd_keyboard),
        std::make_pair(hid_usage_page::generic_desktop, hid_usage::gd_mouse),
        std::make_pair(hid_usage_page::generic_desktop, hid_usage::gd_pointer),
    });
  }

  ~device_observer(void) {
    hid_manager_.stop();
  }

private:
  const grabber_client& grabber_client_;

  hid_manager hid_manager_;
  grabbable_state_manager grabbable_state_manager_;
};
} // namespace krbn
<commit_msg>add log message<commit_after>#pragma once

#include "boost_defs.hpp"

#include "gcd_utility.hpp"
#include "grabbable_state_manager.hpp"
#include "grabber_client.hpp"
#include "hid_manager.hpp"
#include "logger.hpp"
#include "types.hpp"

namespace krbn {
class device_observer final {
public:
  device_observer(const device_observer&) = delete;

  device_observer(const grabber_client& grabber_client) : grabber_client_(grabber_client) {
    grabbable_state_manager_.grabbable_state_changed.connect([this](auto&& registry_entry_id,
                                                                    auto&& grabbable_state,
                                                                    auto&& ungrabbable_temporarily_reason,
                                                                    auto&& time_stamp) {
      grabber_client_.grabbable_state_changed(registry_entry_id,
                                              grabbable_state,
                                              ungrabbable_temporarily_reason,
                                              time_stamp);
    });

    hid_manager_.set_log_enabled(true);

    hid_manager_.device_detecting.connect([](auto&& device) {
      if (iokit_utility::is_karabiner_virtual_hid_device(device)) {
        return false;
      }
      return true;
    });

    hid_manager_.device_detected.connect([this](auto&& human_interface_device) {
      grabbable_state_manager_.update(human_interface_device.get_registry_entry_id(),
                                      grabbable_state::device_error,
                                      ungrabbable_temporarily_reason::none,
                                      mach_absolute_time());

      human_interface_device.device_observed.connect([this](auto&& human_interface_device) {
        logger::get_logger().info("{0} is observed.",
                                  human_interface_device.get_name_for_log());

        if (auto state = grabbable_state_manager_.get_grabbable_state(human_interface_device.get_registry_entry_id())) {
          // Keep grabbable_state if the state is already changed by value_callback.
          if (state->first == grabbable_state::device_error) {
            grabbable_state_manager_.update(human_interface_device.get_registry_entry_id(),
                                            grabbable_state::grabbable,
                                            ungrabbable_temporarily_reason::none,
                                            mach_absolute_time());
          }
        }
      });
      human_interface_device.values_arrived.connect([this](auto&& human_interface_device,
                                                           auto&& event_queue) {
        grabbable_state_manager_.update(event_queue);
      });
      human_interface_device.observe();
    });

    hid_manager_.start({
        std::make_pair(hid_usage_page::generic_desktop, hid_usage::gd_keyboard),
        std::make_pair(hid_usage_page::generic_desktop, hid_usage::gd_mouse),
        std::make_pair(hid_usage_page::generic_desktop, hid_usage::gd_pointer),
    });
  }

  ~device_observer(void) {
    hid_manager_.stop();
  }

private:
  const grabber_client& grabber_client_;

  hid_manager hid_manager_;
  grabbable_state_manager grabbable_state_manager_;
};
} // namespace krbn

{'fraction_non_alphanumeric': 0.0844005554698349, 'fraction_numerical': 0.00015429717636167257, 'mean_word_length': 2.0303880317905563, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 47, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '244541', 'n_tokens_mistral': 1730, 'n_tokens_neox': 1713, 'n_words': 214}