COMContext.cpp (4210B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "COMContext.h" 5 #include <AppInstallerFileLogger.h> 6 #include <winget/TraceLogger.h> 7 #include <winget/OutputDebugStringLogger.h> 8 9 namespace AppInstaller::CLI::Execution 10 { 11 static constexpr std::string_view s_comLogFileNamePrefix = "WinGetCOM"sv; 12 13 NullStream::NullStream() 14 { 15 m_nullOut.reset(new std::ostream(&m_nullStreamBuf)); 16 m_nullIn.reset(new std::istream(&m_nullStreamBuf)); 17 } 18 19 void COMContext::AddProgressCallbackFunction(ProgressCallBackFunction&& f) 20 { 21 std::lock_guard<std::mutex> lock{ m_callbackLock }; 22 m_comProgressCallbacks.push_back(std::move(f)); 23 } 24 25 void COMContext::FireCallbacks(ReportType reportType, uint64_t current, uint64_t maximum, ProgressType progressType, ::AppInstaller::CLI::Workflow::ExecutionStage executionPhase) 26 { 27 // Lock around iterating through the list. Callbacks should not do long running tasks. 28 std::lock_guard<std::mutex> lock{ m_callbackLock }; 29 for (auto& callback : m_comProgressCallbacks) 30 { 31 callback(reportType, current, maximum, progressType, executionPhase); 32 } 33 }; 34 35 void COMContext::BeginProgress() 36 { 37 FireCallbacks(ReportType::BeginProgress, 0, 0, ProgressType::None, m_executionStage); 38 }; 39 40 void COMContext::OnProgress(uint64_t current, uint64_t maximum, ProgressType progressType) 41 { 42 FireCallbacks(ReportType::Progressing, current, maximum, progressType, m_executionStage); 43 } 44 45 void COMContext::SetProgressMessage(std::string_view) 46 { 47 // TODO: Consider sending message to COM progress 48 } 49 50 void COMContext::EndProgress(bool) 51 { 52 FireCallbacks(ReportType::EndProgress, 0, 0, ProgressType::None, m_executionStage); 53 }; 54 55 void COMContext::SetExecutionStage(CLI::Workflow::ExecutionStage executionStage) 56 { 57 m_executionStage = executionStage; 58 FireCallbacks(ReportType::ExecutionPhaseUpdate, 0, 0, ProgressType::None, m_executionStage); 59 GetThreadGlobals().GetTelemetryLogger().SetExecutionStage(static_cast<uint32_t>(m_executionStage)); 60 } 61 62 void COMContext::SetContextLoggers(const std::wstring_view telemetryCorrelationJson, const std::string& caller) 63 { 64 m_correlationData = telemetryCorrelationJson; 65 66 std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> setThreadGlobalsToPreviousState = this->SetForCurrentThread(); 67 68 SetLoggers(); 69 GetThreadGlobals().GetTelemetryLogger().SetTelemetryCorrelationJson(telemetryCorrelationJson); 70 GetThreadGlobals().GetTelemetryLogger().SetCaller(caller); 71 GetThreadGlobals().GetTelemetryLogger().LogStartup(true); 72 } 73 74 std::wstring_view COMContext::GetCorrelationJson() 75 { 76 return m_correlationData; 77 } 78 79 void COMContext::SetLoggers(std::optional<AppInstaller::Logging::Channel> channel, std::optional<AppInstaller::Logging::Level> level) 80 { 81 // Set up debug string logging during initialization 82 Logging::OutputDebugStringLogger::Add(); 83 Logging::Log().SetEnabledChannels(Logging::Channel::All); 84 Logging::Log().SetLevel(Logging::Level::Verbose); 85 86 Logging::Log().SetEnabledChannels(channel.has_value() ? channel.value() : Settings::User().Get<Settings::Setting::LoggingChannelPreference>()); 87 Logging::Log().SetLevel(level.has_value() ? level.value() : Settings::User().Get<Settings::Setting::LoggingLevelPreference>()); 88 89 // TODO: Log to file for COM API calls only when debugging in visual studio 90 Logging::FileLogger::Add(s_comLogFileNamePrefix); 91 92 Logging::OutputDebugStringLogger::Remove(); 93 94 #ifndef AICLI_DISABLE_TEST_HOOKS 95 if (!Settings::User().Get<Settings::Setting::KeepAllLogFiles>()) 96 #endif 97 { 98 // Initiate the background cleanup of the log file location. 99 Logging::FileLogger::BeginCleanup(); 100 } 101 102 Logging::TraceLogger::Add(); 103 104 Logging::EnableWilFailureTelemetry(); 105 } 106 }