Bug 1674277 - Make AUS.stopDownload asynchronous r=nalexander,preferences-reviewers

The Downloader's cleanup function really ought to be asynchronous. The observer for "quit-application" is already asynchronous, so there's no problem there. But really, we ought to be cleaning up each downloader that we use, not just the last one. Which means that the cleanup ought to happen in AUS.stopDownload. So this patch will convert AUS.stopDownload to be asynchronous so that we can properly clean up the downloader from there.

Differential Revision: https://phabricator.services.mozilla.com/D110646
This commit is contained in:
Kirk Steuber 2021-04-05 19:52:12 +00:00
Родитель a6c437c109
Коммит b920b21c76
5 изменённых файлов: 31 добавлений и 24 удалений

Просмотреть файл

@ -1983,7 +1983,7 @@ var gMainPane = {
let aus = Cc["@mozilla.org/updates/update-service;1"].getService(
Ci.nsIApplicationUpdateService
);
aus.stopDownload();
await aus.stopDownload();
um.cleanupReadyUpdate();
um.cleanupDownloadingUpdate();
}

Просмотреть файл

@ -1635,7 +1635,7 @@ function getPatchOfType(update, patch_type) {
*
* @param postStaging true if we have just attempted to stage an update.
*/
function handleFallbackToCompleteUpdate(postStaging) {
async function handleFallbackToCompleteUpdate(postStaging) {
// If we failed to install an update, we need to fall back to a complete
// update. If the install directory has been modified, more partial updates
// will fail for the same reason. Since we only download partial updates
@ -1661,7 +1661,7 @@ function handleFallbackToCompleteUpdate(postStaging) {
return;
}
aus.stopDownload();
await aus.stopDownload();
cleanupActiveUpdates();
if (!update.selectedPatch) {
@ -2579,7 +2579,7 @@ UpdateService.prototype = {
// intentional fallthrough
case "test-post-update-processing":
// Clean up any extant updates
this._postUpdateProcessing();
await this._postUpdateProcessing();
break;
case "network:offline-status-changed":
this._offlineStatusChanged(data);
@ -2625,7 +2625,7 @@ UpdateService.prototype = {
// Windows BITS are not stopped since they don't require Firefox to be
// running to perform the download.
if (this._downloader && !this._downloader.usingBits) {
this.stopDownload();
await this.stopDownload();
}
// Prevent leaking the downloader (bug 454964)
this._downloader = null;
@ -2666,7 +2666,7 @@ UpdateService.prototype = {
* notify the user of install success.
*/
/* eslint-disable-next-line complexity */
_postUpdateProcessing: function AUS__postUpdateProcessing() {
_postUpdateProcessing: async function AUS__postUpdateProcessing() {
if (this.disabledByPolicy) {
// This function is a point when we can potentially enter the update
// system, even with update disabled. Make sure that we do not continue
@ -2984,7 +2984,7 @@ UpdateService.prototype = {
}
// Something went wrong with the patch application process.
handleFallbackToCompleteUpdate(false);
await handleFallbackToCompleteUpdate(false);
}
},
@ -3937,16 +3937,16 @@ UpdateService.prototype = {
/**
* See nsIUpdateService.idl
*/
stopDownload: function AUS_stopDownload() {
stopDownload: async function AUS_stopDownload() {
if (this.isDownloading) {
this._downloader.cancel();
await this._downloader.cancel();
} else if (this._retryTimer) {
// Download status is still considered as 'downloading' during retry.
// We need to cancel both retry and download at this stage.
this._retryTimer.cancel();
this._retryTimer = null;
if (this._downloader) {
this._downloader.cancel();
await this._downloader.cancel();
}
}
this._downloader = null;
@ -4449,7 +4449,7 @@ UpdateManager.prototype = {
update.state = getBestPendingState();
writeStatusFile(getReadyUpdateDir(), update.state);
} else if (!handleUpdateFailure(update, parts[1])) {
handleFallbackToCompleteUpdate(true);
await handleFallbackToCompleteUpdate(true);
}
}
if (update.state == STATE_APPLIED && shouldUseService()) {
@ -4466,14 +4466,13 @@ UpdateManager.prototype = {
// Send an observer notification which the app update doorhanger uses to
// display a restart notification after any langpacks have staged.
promiseLangPacksUpdated(update).then(() => {
LOG(
"UpdateManager:refreshUpdateStatus - Notifying observers that " +
"the update was staged. topic: update-staged, status: " +
update.state
);
Services.obs.notifyObservers(update, "update-staged", update.state);
});
await promiseLangPacksUpdated(update);
LOG(
"UpdateManager:refreshUpdateStatus - Notifying observers that " +
"the update was staged. topic: update-staged, status: " +
update.state
);
Services.obs.notifyObservers(update, "update-staged", update.state);
},
/**

Просмотреть файл

@ -341,8 +341,10 @@ interface nsIApplicationUpdateService : nsISupports
* calling nsIRequest::Cancel on the download's nsIRequest. When downloading
* with nsIIncrementalDownload, this will leave the partial download in place.
* When downloading with BITS, any partial download progress will be removed.
*
* @returns A Promise that resolves once the download has been stopped.
*/
void stopDownload();
Promise stopDownload();
/**
* Whether or not there is an download happening at the moment.
@ -554,8 +556,10 @@ interface nsIUpdateManager : nsISupports
/**
* Refresh the update status based on the information in update.status.
*
* @returns A Promise that resolves after the update status is refreshed.
*/
void refreshUpdateStatus();
Promise refreshUpdateStatus();
/**
* The user agreed to proceed with an elevated update and we are now

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function run_test() {
async function run_test() {
setupTestCommon();
debugDump(
@ -33,6 +33,6 @@ function run_test() {
// Cancel the download early to prevent it writing the update xml files during
// shutdown.
gAUS.stopDownload();
await gAUS.stopDownload();
executeSoon(doTestFinish);
}

Просмотреть файл

@ -28,6 +28,7 @@
#include "nsIObserverService.h"
#include "nsNetCID.h"
#include "mozilla/Services.h"
#include "mozilla/dom/Promise.h"
#ifdef XP_MACOSX
# include "nsILocalFileMac.h"
@ -1068,7 +1069,10 @@ void nsUpdateProcessor::UpdateDone() {
nsCOMPtr<nsIUpdateManager> um =
do_GetService("@mozilla.org/updates/update-manager;1");
if (um) {
um->RefreshUpdateStatus();
// This completes asynchronously, but nothing else that we are doing in this
// function requires waiting for this to complete.
RefPtr<mozilla::dom::Promise> outPromise;
um->RefreshUpdateStatus(getter_AddRefs(outPromise));
}
ShutdownWatcherThread();