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 }