/ src / runner / settings_telemetry.cpp
settings_telemetry.cpp
 1  #pragma once
 2  #include "pch.h"
 3  #include "settings_telemetry.h"
 4  #include <Windows.h>
 5  #include <thread>
 6  #include <common/logger/logger.h>
 7  #include <common/utils/timeutil.h>
 8  #include <common/SettingsAPI/settings_helpers.h>
 9  #include <filesystem>
10  #include "powertoy_module.h"
11  
12  using JsonObject = winrt::Windows::Data::Json::JsonObject;
13  using JsonValue = winrt::Windows::Data::Json::JsonValue;
14  
15  std::wstring get_info_file_path()
16  {
17      std::filesystem::path settingsFilePath(PTSettingsHelper::get_root_save_folder_location());
18      settingsFilePath = settingsFilePath.append(settings_telemetry::send_info_file);
19      return settingsFilePath.wstring();
20  }
21  
22  std::optional<time_t> get_last_send_time()
23  {
24      auto settings = json::from_file(get_info_file_path());
25      if (!settings.has_value() || !settings.value().HasKey(settings_telemetry::last_send_option))
26      {
27          return std::nullopt;
28      }
29  
30      auto stringTime = (std::wstring)settings.value().GetNamedString(settings_telemetry::last_send_option);
31      return timeutil::from_string(stringTime);
32  }
33  
34  void update_last_send_time(time_t time)
35  {
36      auto settings = JsonObject();
37      settings.SetNamedValue(settings_telemetry::last_send_option, JsonValue::CreateStringValue(timeutil::to_string(time)));
38      json::to_file(get_info_file_path(), settings);
39  }
40  
41  void send()
42  {
43      for (auto& [name, powertoy] : modules())
44      {
45          if (powertoy->is_enabled())
46          {
47              try
48              {
49                  powertoy->send_settings_telemetry();
50              }
51              catch (...)
52              {
53                  Logger::error(L"Failed to send telemetry for {} module", name);
54              }
55          }
56      }
57  }
58  
59  void run_interval()
60  {
61      auto time = get_last_send_time();
62      long long wait_time = 24 * 3600;
63      long long left_to_wait = 0;
64      if (time.has_value())
65      {
66          left_to_wait = max(0, wait_time - timeutil::diff::in_seconds(timeutil::now(), time.value()));
67      }
68  
69      Sleep(static_cast<DWORD>(left_to_wait * 1000));
70      send();
71      update_last_send_time(timeutil::now());
72  
73      while (true)
74      {
75          Sleep(static_cast<DWORD>(wait_time * 1000));
76          send();
77          update_last_send_time(timeutil::now());
78      }
79  }
80  
81  void settings_telemetry::init()
82  {
83      std::thread([]() {
84          try
85          {
86              run_interval();
87          }
88          catch (...)
89          {
90              Logger::error("Failed to send settings telemetry");
91          }
92      }).detach();
93  }