Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
UpdateManager Class Referencefinal

A class that managing of updates. More...

#include <UpdateManager.h>

Inheritance diagram for UpdateManager:
[legend]
Collaboration diagram for UpdateManager:
[legend]

Public Member Functions

 UpdateManager ()=default
 
void GetUpdates (bool ignoreNetworkErrors, bool configurableNotification)
 
VersionPatch GetVersionPatch () const
 

Static Public Member Functions

static UpdateManagerGetInstance ()
 
static void Start (bool suppressModal)
 

Private Member Functions

void OnTimer (wxTimerEvent &event)
 
bool IsTimeForUpdatesChecking ()
 Scheduling update time for avoiding multiplying update notifications. More...
 

Private Attributes

UpdateDataParser mUpdateDataParser
 
VersionPatch mVersionPatch
 
wxTimer mTimer
 
std::unique_ptr< BasicUI::ProgressDialogmProgressDialog
 
std::string mAudacityInstallerPath
 
std::ofstream mAudacityInstaller
 
std::mutex mUpdateMutex
 
bool mOnProgress { false }
 

Detailed Description

A class that managing of updates.

Opt-in request and show update dialog by the scheduled time. Have a built-in check that allows avoiding multiplying update notifications when multiple Audacity windows are shown.

Definition at line 33 of file UpdateManager.h.

Constructor & Destructor Documentation

◆ UpdateManager()

UpdateManager::UpdateManager ( )
default

Member Function Documentation

◆ GetInstance()

UpdateManager & UpdateManager::GetInstance ( )
static

Definition at line 53 of file UpdateManager.cpp.

54{
55 static UpdateManager updateManager;
56
57 return updateManager;
58}
A class that managing of updates.
Definition: UpdateManager.h:34

Referenced by Start().

Here is the caller graph for this function:

◆ GetUpdates()

void UpdateManager::GetUpdates ( bool  ignoreNetworkErrors,
bool  configurableNotification 
)

Definition at line 92 of file UpdateManager.cpp.

93{
94#if AUDACITY_BUILD_LEVEL == 0
95 const auto url = "https://updates.audacityteam.org/builds/alpha.xml";
96#elif AUDACITY_BUILD_LEVEL == 1
97 const auto url = "https://updates.audacityteam.org/builds/beta.xml";
98#else
99 const auto url = "https://updates.audacityteam.org/feed/latest.xml";
100#endif
101
102 const audacity::network_manager::Request request(url);
104
105 response->setRequestFinishedCallback([response, ignoreNetworkErrors, configurableNotification, this](audacity::network_manager::IResponse*) {
106
107 // We don't' want to duplicate the updates checking if that already launched.
108 {
109 std::lock_guard<std::mutex> lock(mUpdateMutex);
110 if (mOnProgress)
111 {
112 response->abort();
113 return;
114 }
115 mOnProgress = true;
116 }
117
118 using namespace BasicUI;
119 auto gAudioIO = AudioIO::Get();
120 if (response->getError() != audacity::network_manager::NetworkError::NoError)
121 {
122 if (!ignoreNetworkErrors)
123 {
124 gAudioIO->CallAfterRecording([] {ShowErrorDialog( {},
125 XC("Error checking for update", "update dialog"),
126 XC("Unable to connect to Audacity update server.", "update dialog"),
127 wxString(),
128 ErrorDialogOptions{ ErrorDialogType::ModalErrorReport });
129 });
130 }
131
132 mOnProgress = false;
133 return;
134 }
135
137 {
138 if (!ignoreNetworkErrors)
139 {
140 gAudioIO->CallAfterRecording([] {ShowErrorDialog( {},
141 XC("Error checking for update", "update dialog"),
142 XC("Update data was corrupted.", "update dialog"),
143 wxString(),
144 ErrorDialogOptions{ ErrorDialogType::ModalErrorReport });
145 });
146 }
147
148 mOnProgress = false;
149 return;
150 }
151
152#if UPDATE_LOCAL_TESTING == 0
154#endif
155 {
156 gAudioIO->CallAfterRecording([this, ignoreNetworkErrors, configurableNotification] {
157 UpdatePopupDialog dlg(nullptr, mVersionPatch, configurableNotification);
158 const int code = dlg.ShowModal();
159
160 if (code == wxID_YES)
161 {
162 const audacity::network_manager::Request downloadRequest(mVersionPatch.download.ToStdString());
163 auto downloadResponse = audacity::network_manager::NetworkManager::GetInstance().doGet(downloadRequest);
164
165 // Called once, when downloading is real will finish.
166 downloadResponse->setRequestFinishedCallback([downloadResponse, ignoreNetworkErrors, this](audacity::network_manager::IResponse*) {
167 // First - close all opened resources.
168 wxTheApp->CallAfter([this]{ mProgressDialog.reset(); });
169
170 if (mAudacityInstaller.is_open())
171 mAudacityInstaller.close();
172
173 if (downloadResponse->getError() != audacity::network_manager::NetworkError::NoError)
174 {
175 if (!ignoreNetworkErrors)
176 {
177 wxTheApp->CallAfter([] {ShowErrorDialog( {},
178 XC("Error downloading update", "update dialog"),
179 XC("Can't open the Audacity download link.", "update dialog"),
180 wxString(),
181 ErrorDialogOptions{ ErrorDialogType::ModalErrorReport });
182 });
183 }
184
185 mOnProgress = false;
186 return;
187 }
188
189 const wxPlatformInfo& info = wxPlatformInfo::Get();
190 if ((info.GetOperatingSystemId() & wxOS_WINDOWS) ||
191 info.GetOperatingSystemId() & wxOS_MAC)
192 {
193 if (wxFileName(mAudacityInstallerPath).Exists())
194 {
195 std::string cmd = info.GetOperatingSystemId() & wxOS_MAC ? "Open " + mAudacityInstallerPath : mAudacityInstallerPath;
196 wxTheApp->CallAfter([cmd] { wxExecute(cmd, wxEXEC_ASYNC); });
197 }
198 }
199
200 mOnProgress = false;
201 }
202 );
203
204 auto audacityPatchFilename = wxFileName(mVersionPatch.download).GetName();
205
206 mProgressDialog = BasicUI::MakeProgress(XO("Audacity update"), XO("Downloading %s").Format(audacityPatchFilename));
207 wxASSERT(mProgressDialog);
208
209 wxString installerExtension;
210 const wxPlatformInfo& info = wxPlatformInfo::Get();
211 if (info.GetOperatingSystemId() & wxOS_WINDOWS)
212 installerExtension = "exe";
213 else if(info.GetOperatingSystemId() & wxOS_MAC)
214 installerExtension = "dmg";
215
216 mAudacityInstallerPath = wxFileName(
217 wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads), audacityPatchFilename, installerExtension)
218 .GetFullPath()
219 .ToStdString();
220
221 mAudacityInstaller.open(mAudacityInstallerPath, std::ios::binary);
222
223 // Called each time, since downloading for update progress status.
224 downloadResponse->setDownloadProgressCallback(
225 [this](int64_t current, int64_t expected) {
226
227 wxTheApp->CallAfter([this, current, expected]{
228 if(mProgressDialog != nullptr)
229 mProgressDialog->Poll(current, expected);
230 });
231 }
232 );
233
234 // Called each time, since downloading for get data.
235 downloadResponse->setOnDataReceivedCallback([downloadResponse, this](audacity::network_manager::IResponse*) {
236 if (downloadResponse->getError() == audacity::network_manager::NetworkError::NoError)
237 {
238 std::vector<char> buffer(downloadResponse->getBytesAvailable());
239
240 size_t bytes = downloadResponse->readData(buffer.data(), buffer.size());
241
242 if (mAudacityInstaller.is_open())
243 mAudacityInstaller.write(buffer.data(), buffer.size());
244 }
245 }
246 );
247
248 }
249 else if (code == wxID_NO)
250 {
251 mOnProgress = false;
252 }
253 });
254 }
255#if UPDATE_LOCAL_TESTING == 0
256 else // mVersionPatch.version > CurrentBuildVersion()
257 {
258 // That also shows, that updates checking was called manually from menu.
259 if (!configurableNotification)
260 {
261 gAudioIO->CallAfterRecording([] {
262 NoUpdatesAvailableDialog(nullptr).ShowModal();
263 });
264 }
265
266 mOnProgress = false;
267 }
268#endif
269 });
270}
XO("Cut/Copy/Paste")
#define XC(s, c)
Definition: Internat.h:37
static VersionId CurrentBuildVersion()
Return version (VersionId) object with current Audacity build version.
Definition: VersionId.h:47
static AudioIO * Get()
Definition: AudioIO.cpp:126
Abstract base class used in importing a file.
Information dialog about no updates available, that allows to navigate to settings quickly.
bool Parse(const VersionPatch::UpdateDataFormat &updateData, VersionPatch *versionPatch)
Parsing from update data format to VersionPatch fields.
std::unique_ptr< BasicUI::ProgressDialog > mProgressDialog
Definition: UpdateManager.h:56
std::string mAudacityInstallerPath
Definition: UpdateManager.h:58
std::mutex mUpdateMutex
Definition: UpdateManager.h:61
UpdateDataParser mUpdateDataParser
Definition: UpdateManager.h:46
std::ofstream mAudacityInstaller
Definition: UpdateManager.h:59
VersionPatch mVersionPatch
Definition: UpdateManager.h:47
Show dialog window with update information for the user.
Interface, that provides access to the data from the HTTP response.
Definition: IResponse.h:113
ResponsePtr doGet(const Request &request)
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Definition: BasicUI.h:264
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:201
std::unique_ptr< ProgressDialog > MakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags=(ProgressShowStop|ProgressShowCancel), const TranslatableString &remainingLabelText={})
Create and display a progress dialog.
Definition: BasicUI.h:294
Options for variations of error dialogs; the default is for modal dialogs.
Definition: BasicUI.h:52
VersionId version
Definition: VersionPatch.h:20
std::string UpdateDataFormat
Definition: VersionPatch.h:16
wxString download
Definition: VersionPatch.h:22

References CurrentBuildVersion(), audacity::network_manager::NetworkManager::doGet(), VersionPatch::download, AudioIO::Get(), BasicUI::Get(), audacity::network_manager::NetworkManager::GetInstance(), BasicUI::MakeProgress(), mAudacityInstaller, mAudacityInstallerPath, mOnProgress, mProgressDialog, mUpdateDataParser, mUpdateMutex, mVersionPatch, audacity::network_manager::NoError, UpdateDataParser::Parse(), BasicUI::ShowErrorDialog(), VersionPatch::version, XC, and XO().

Referenced by OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetVersionPatch()

VersionPatch UpdateManager::GetVersionPatch ( ) const

Definition at line 87 of file UpdateManager.cpp.

88{
89 return mVersionPatch;
90}

References mVersionPatch.

◆ IsTimeForUpdatesChecking()

bool UpdateManager::IsTimeForUpdatesChecking ( )
private

Scheduling update time for avoiding multiplying update notifications.

Definition at line 288 of file UpdateManager.cpp.

289{
290 // We use atoll here, so there is no need to handle the exception,
291 // if prefsUpdateScheduledTime is corrupted.
292 // atoll will return 0 on failure, which suits us well.
293 const TimePoint nextUpdatesCheckingTime(std::chrono::milliseconds(
294 atoll(gPrefs->Read(prefsUpdateScheduledTime, "0").c_str())));
295
296 // Get current time
297 const TimePoint currentTime = Clock::now();
298
299 // If next update time 0 or less then current time -> show update dialog,
300 // else this condition allow us to avoid from duplicating update notifications.
301 if (nextUpdatesCheckingTime < currentTime)
302 {
303
304 // Round down the nextUpdatesChecking time to a day.
305 // This is required to ensure, that update is
306 // checked daily
307 using DayDuration =
308 std::chrono::duration<int32_t, std::ratio<60 * 60 * 24>>;
309
310 const auto postponeUpdateUntil =
311 std::chrono::time_point_cast<DayDuration>(
312 currentTime) + DayDuration(1);
313
314 const std::chrono::milliseconds postponeUpdateUntilMS(
315 postponeUpdateUntil.time_since_epoch());
316
317 gPrefs->Write(
319 wxString(std::to_string(postponeUpdateUntilMS.count())));
320
321 gPrefs->Flush();
322
323 return true;
324 }
325
326 return false;
327}
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
static const char * prefsUpdateScheduledTime
Clock::time_point TimePoint
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0

References audacity::BasicSettings::Flush(), gPrefs, prefsUpdateScheduledTime, audacity::BasicSettings::Read(), and audacity::BasicSettings::Write().

Referenced by OnTimer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnTimer()

void UpdateManager::OnTimer ( wxTimerEvent &  event)
private

Definition at line 272 of file UpdateManager.cpp.

273{
274 bool updatesCheckingEnabled = DefaultUpdatesCheckingFlag->Read();
275
276#if UPDATE_LOCAL_TESTING == 0
277 if (updatesCheckingEnabled && IsTimeForUpdatesChecking())
278#endif
279 {
280 GetUpdates(true, true);
281 }
282
283 mTimer.StartOnce(std::chrono::duration_cast<std::chrono::milliseconds>(
285 .count());
286}
StickySetting< BoolSetting > DefaultUpdatesCheckingFlag
Definition: Prefs.cpp:63
constexpr Duration updatesCheckInterval
void GetUpdates(bool ignoreNetworkErrors, bool configurableNotification)
wxTimer mTimer
Definition: UpdateManager.h:49
bool IsTimeForUpdatesChecking()
Scheduling update time for avoiding multiplying update notifications.

References DefaultUpdatesCheckingFlag, GetUpdates(), IsTimeForUpdatesChecking(), mTimer, and updatesCheckInterval.

Here is the call graph for this function:

◆ Start()

void UpdateManager::Start ( bool  suppressModal)
static

Definition at line 60 of file UpdateManager.cpp.

61{
62 auto& instance = GetInstance();
63
64 // Show the dialog only once.
65 if (!suppressModal && !prefUpdatesNoticeShown.Read())
66 {
67 // DefaultUpdatesCheckingFlag survives the "Reset Preferences"
68 // action, so check, if the updates were previously disabled as well.
70 {
71 UpdateNoticeDialog notice(nullptr);
72
73 notice.ShowModal();
74 }
75
77 gPrefs->Flush();
78 }
79
80 static std::once_flag flag;
81 std::call_once(flag, [&instance] {
82 instance.mTimer.SetOwner(&instance, ID_TIMER);
83 instance.mTimer.StartOnce(1);
84 });
85}
@ ID_TIMER
static BoolSetting prefUpdatesNoticeShown(wxT("/Update/UpdateNoticeShown"), false)
static std::once_flag flag
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:259
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:207
static UpdateManager & GetInstance()
Dialog, that notifies the users about automatic updates checking.

References DefaultUpdatesCheckingFlag, flag, audacity::BasicSettings::Flush(), GetInstance(), gPrefs, ID_TIMER, prefUpdatesNoticeShown, Setting< T >::Read(), and Setting< T >::Write().

Referenced by AudacityApp::InitPart2().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mAudacityInstaller

std::ofstream UpdateManager::mAudacityInstaller
private

Definition at line 59 of file UpdateManager.h.

Referenced by GetUpdates().

◆ mAudacityInstallerPath

std::string UpdateManager::mAudacityInstallerPath
private

Definition at line 58 of file UpdateManager.h.

Referenced by GetUpdates().

◆ mOnProgress

bool UpdateManager::mOnProgress { false }
private

Definition at line 62 of file UpdateManager.h.

Referenced by GetUpdates().

◆ mProgressDialog

std::unique_ptr<BasicUI::ProgressDialog> UpdateManager::mProgressDialog
private

Definition at line 56 of file UpdateManager.h.

Referenced by GetUpdates().

◆ mTimer

wxTimer UpdateManager::mTimer
private

Definition at line 49 of file UpdateManager.h.

Referenced by OnTimer().

◆ mUpdateDataParser

UpdateDataParser UpdateManager::mUpdateDataParser
private

Definition at line 46 of file UpdateManager.h.

Referenced by GetUpdates().

◆ mUpdateMutex

std::mutex UpdateManager::mUpdateMutex
private

Definition at line 61 of file UpdateManager.h.

Referenced by GetUpdates().

◆ mVersionPatch

VersionPatch UpdateManager::mVersionPatch
private

Definition at line 47 of file UpdateManager.h.

Referenced by GetUpdates(), and GetVersionPatch().


The documentation for this class was generated from the following files: