Progress.cpp (4317B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "AppInstallerProgress.h" 5 #include <AppInstallerErrors.h> 6 7 namespace AppInstaller 8 { 9 HRESULT ToHRESULT(CancelReason reason) 10 { 11 HRESULT hr = E_ABORT; 12 13 switch (reason) 14 { 15 case CancelReason::CtrlCSignal: 16 hr = APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED; 17 break; 18 case CancelReason::AppShutdown: 19 hr = APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED; 20 break; 21 } 22 23 return hr; 24 } 25 26 ProgressCallback::ProgressCallback(IProgressSink* sink) : m_sink(sink) 27 { 28 } 29 30 void ProgressCallback::BeginProgress() 31 { 32 IProgressSink* sink = GetSink(); 33 if (sink) 34 { 35 sink->BeginProgress(); 36 } 37 } 38 39 void ProgressCallback::OnProgress(uint64_t current, uint64_t maximum, ProgressType type) 40 { 41 IProgressSink* sink = GetSink(); 42 if (sink) 43 { 44 sink->OnProgress(current, maximum, type); 45 } 46 } 47 48 void ProgressCallback::SetProgressMessage(std::string_view message) 49 { 50 IProgressSink* sink = GetSink(); 51 if (sink) 52 { 53 sink->SetProgressMessage(message); 54 } 55 } 56 57 void ProgressCallback::EndProgress(bool hideProgressWhenDone) 58 { 59 IProgressSink* sink = GetSink(); 60 if (sink) 61 { 62 sink->EndProgress(hideProgressWhenDone); 63 } 64 }; 65 66 bool ProgressCallback::IsCancelledBy(CancelReason cancelReasons) 67 { 68 THROW_HR_IF(E_UNEXPECTED, cancelReasons == CancelReason::None); 69 return WI_IsAnyFlagSet(cancelReasons, m_cancelReason); 70 } 71 72 [[nodiscard]] IProgressCallback::CancelFunctionRemoval ProgressCallback::SetCancellationFunction(std::function<void()>&& f) 73 { 74 m_cancellationFunction = std::move(f); 75 if (m_cancellationFunction) 76 { 77 return IProgressCallback::CancelFunctionRemoval(this); 78 } 79 else 80 { 81 return {}; 82 } 83 } 84 85 bool ProgressCallback::Wait(IProgressCallback& progress, std::chrono::milliseconds millisecondsToWait) 86 { 87 wil::unique_event calledEvent; 88 calledEvent.create(); 89 90 auto cancellationFunc = progress.SetCancellationFunction([&calledEvent]() 91 { 92 calledEvent.SetEvent(); 93 }); 94 95 if (calledEvent.wait(static_cast<DWORD>(millisecondsToWait.count()))) 96 { 97 return false; 98 } 99 100 return true; 101 } 102 103 void ProgressCallback::Cancel(CancelReason reason) 104 { 105 m_cancelReason = reason; 106 if (m_cancellationFunction) 107 { 108 m_cancellationFunction(); 109 } 110 } 111 112 IProgressSink* ProgressCallback::GetSink() 113 { 114 return m_sink.load(); 115 } 116 117 PartialPercentProgressCallback::PartialPercentProgressCallback(IProgressCallback& baseCallback, uint64_t globalMax) : 118 m_baseCallback(baseCallback), m_globalMax(globalMax) 119 { 120 } 121 122 void PartialPercentProgressCallback::BeginProgress() 123 { 124 THROW_HR(E_NOTIMPL); 125 } 126 127 void PartialPercentProgressCallback::OnProgress(uint64_t current, uint64_t maximum, ProgressType type) 128 { 129 THROW_HR_IF(E_UNEXPECTED, ProgressType::Percent != type); 130 131 m_baseCallback.OnProgress(m_rangeMin + (m_rangeMax - m_rangeMin) * current / maximum, m_globalMax, type); 132 } 133 134 void PartialPercentProgressCallback::SetProgressMessage(std::string_view message) 135 { 136 m_baseCallback.SetProgressMessage(message); 137 } 138 139 void PartialPercentProgressCallback::EndProgress(bool) 140 { 141 THROW_HR(E_NOTIMPL); 142 } 143 144 IProgressCallback::CancelFunctionRemoval PartialPercentProgressCallback::SetCancellationFunction(std::function<void()>&& f) 145 { 146 return m_baseCallback.SetCancellationFunction(std::move(f)); 147 } 148 149 void PartialPercentProgressCallback::SetRange(uint64_t rangeMin, uint64_t rangeMax) 150 { 151 THROW_HR_IF(E_INVALIDARG, rangeMin > rangeMax || rangeMax > m_globalMax); 152 m_rangeMin = rangeMin; 153 m_rangeMax = rangeMax; 154 } 155 }