Bug 1785046 - Part 4: Use async move on printing to file on Windows. r=nika,emilio

Differential Revision: https://phabricator.services.mozilla.com/D163509
This commit is contained in:
David Shin 2022-12-19 15:42:49 +00:00
parent aab93348e9
commit 9b9c76aa00
4 changed files with 53 additions and 22 deletions

View File

@ -6,8 +6,14 @@
#include "nsIDeviceContextSpec.h"
#include "gfxPoint.h"
#include "mozilla/gfx/PrintPromise.h"
#include "nsError.h"
#include "nsIPrintSettings.h"
#include "mozilla/Components.h"
#include "mozilla/TaskQueue.h"
using mozilla::MakeRefPtr;
using mozilla::gfx::PrintEndDocumentPromise;
// We have some platform specific code here rather than in the appropriate
@ -58,3 +64,24 @@ nsIDeviceContextSpec::EndDocumentPromiseFromResult(nsresult aResult,
? PrintEndDocumentPromise::CreateAndResolve(true, aSite)
: PrintEndDocumentPromise::CreateAndReject(aResult, aSite);
}
RefPtr<PrintEndDocumentPromise> nsIDeviceContextSpec::EndDocumentAsync(
const char* aCallSite, AsyncEndDocumentFunction aFunction) {
auto promise =
MakeRefPtr<PrintEndDocumentPromise::Private>("PrintEndDocumentPromise");
NS_DispatchBackgroundTask(
NS_NewRunnableFunction(
"EndDocumentAsync",
[promise, function = std::move(aFunction)]() mutable {
const auto result = function();
if (NS_SUCCEEDED(result)) {
promise->Resolve(true, __func__);
} else {
promise->Reject(result, __func__);
}
}),
NS_DISPATCH_EVENT_MAY_BLOCK);
return promise;
}

View File

@ -10,6 +10,7 @@
#include "nsISupports.h"
#include "mozilla/StaticPrefs_print.h"
#include "mozilla/gfx/PrintPromise.h"
#include "mozilla/MoveOnlyFunction.h"
class nsIWidget;
class nsIPrintSettings;
@ -82,6 +83,10 @@ class nsIDeviceContextSpec : public nsISupports {
NS_IMETHOD EndPage() = 0;
protected:
using AsyncEndDocumentFunction = mozilla::MoveOnlyFunction<nsresult()>;
static RefPtr<mozilla::gfx::PrintEndDocumentPromise> EndDocumentAsync(
const char* aCallSite, AsyncEndDocumentFunction aFunction);
static RefPtr<mozilla::gfx::PrintEndDocumentPromise>
EndDocumentPromiseFromResult(nsresult aResult, const char* aSite);

View File

@ -333,20 +333,15 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecWin::MakePrintTarget() {
}
RefPtr<PrintEndDocumentPromise> nsDeviceContextSpecWin::EndDocument() {
return nsIDeviceContextSpec::EndDocumentPromiseFromResult(DoEndDocument(),
__func__);
}
nsresult nsDeviceContextSpecWin::DoEndDocument() {
if (mPrintSettings->GetOutputDestination() !=
nsIPrintSettings::kOutputDestinationFile ||
mOutputFormat != nsIPrintSettings::kOutputFormatPDF) {
return NS_OK;
return PrintEndDocumentPromise::CreateAndResolve(true, __func__);
}
#ifdef MOZ_ENABLE_SKIA_PDF
if (mPrintViaSkPDF) {
return NS_OK;
return PrintEndDocumentPromise::CreateAndResolve(true, __func__);
}
#endif
@ -356,25 +351,32 @@ nsresult nsDeviceContextSpecWin::DoEndDocument() {
mPrintSettings->GetToFileName(targetPath);
if (targetPath.IsEmpty()) {
return NS_OK;
return PrintEndDocumentPromise::CreateAndResolve(true, __func__);
}
// We still need to move the file to its actual destination.
nsCOMPtr<nsIFile> destFile;
MOZ_TRY(NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile)));
nsAutoString destLeafName;
MOZ_TRY(destFile->GetLeafName(destLeafName));
auto rv = NS_NewLocalFile(targetPath, false, getter_AddRefs(destFile));
if (NS_FAILED(rv)) {
return PrintEndDocumentPromise::CreateAndReject(rv, __func__);
}
nsCOMPtr<nsIFile> destDir;
MOZ_TRY(destFile->GetParent(getter_AddRefs(destDir)));
return nsIDeviceContextSpec::EndDocumentAsync(
__func__,
[destFile = std::move(destFile),
tempFile = std::move(mTempFile)]() -> nsresult {
nsAutoString destLeafName;
MOZ_TRY(destFile->GetLeafName(destLeafName));
// This should be fine - Windows API calls usually prevent moving between
// different volumes (See Win32 API's `MOVEFILE_COPY_ALLOWED` flag), but we
// handle that down this call.
MOZ_TRY(mTempFile->MoveTo(destDir, destLeafName));
mTempFile = nullptr;
nsCOMPtr<nsIFile> destDir;
MOZ_TRY(destFile->GetParent(getter_AddRefs(destDir)));
return NS_OK;
// This should be fine - Windows API calls usually prevent moving
// between different volumes (See Win32 API's `MOVEFILE_COPY_ALLOWED`
// flag), but we handle that down this call.
MOZ_TRY(tempFile->MoveTo(destDir, destLeafName));
return NS_OK;
});
}
//----------------------------------------------------------------------------------

View File

@ -69,9 +69,6 @@ class nsDeviceContextSpecWin : public nsIDeviceContextSpec {
// A temporary file to create an "anonymous" print target. See bug 1664253,
// this should ideally not be needed.
nsCOMPtr<nsIFile> mTempFile;
private:
nsresult DoEndDocument();
};
//-------------------------------------------------------------------------