diff --git a/browser/components/contentanalysis/content/ContentAnalysis.sys.mjs b/browser/components/contentanalysis/content/ContentAnalysis.sys.mjs index c710f098cbf0..25ef6c3843cc 100644 --- a/browser/components/contentanalysis/content/ContentAnalysis.sys.mjs +++ b/browser/components/contentanalysis/content/ContentAnalysis.sys.mjs @@ -300,10 +300,10 @@ export const ContentAnalysis = { ); return; } - const analysisType = request.analysisType; + const operation = request.analysisType; // For operations that block browser interaction, show the "slow content analysis" // dialog faster - let slowTimeoutMs = this._shouldShowBlockingNotification(analysisType) + let slowTimeoutMs = this._shouldShowBlockingNotification(operation) ? this._SLOW_DLP_NOTIFICATION_BLOCKING_TIMEOUT_MS : this._SLOW_DLP_NOTIFICATION_NONBLOCKING_TIMEOUT_MS; let browsingContext = request.windowGlobalParent?.browsingContext; @@ -333,7 +333,7 @@ export const ContentAnalysis = { timer: lazy.setTimeout(() => { this.dlpBusyViewsByTopBrowsingContext.setEntry(browsingContext, { notification: this._showSlowCAMessage( - analysisType, + operation, request, resourceNameOrOperationType, browsingContext @@ -450,10 +450,7 @@ export const ContentAnalysis = { } if (this._SHOW_NOTIFICATIONS) { - let topWindow = - aBrowsingContext.topChromeWindow ?? - aBrowsingContext.embedderWindowGlobal.browsingContext.topChromeWindow; - const notification = new topWindow.Notification( + const notification = new aBrowsingContext.topChromeWindow.Notification( this.l10n.formatValueSync("contentanalysis-notification-title"), { body: aMessage, @@ -472,10 +469,10 @@ export const ContentAnalysis = { return null; }, - _shouldShowBlockingNotification(aAnalysisType) { + _shouldShowBlockingNotification(aOperation) { return !( - aAnalysisType == Ci.nsIContentAnalysisRequest.eFileDownloaded || - aAnalysisType == Ci.nsIContentAnalysisRequest.ePrint + aOperation == Ci.nsIContentAnalysisRequest.eFileDownloaded || + aOperation == Ci.nsIContentAnalysisRequest.ePrint ); }, @@ -491,9 +488,6 @@ export const ContentAnalysis = { case Ci.nsIContentAnalysisRequest.eDroppedText: l10nId = "contentanalysis-operationtype-dropped-text"; break; - case Ci.nsIContentAnalysisRequest.eOperationPrint: - l10nId = "contentanalysis-operationtype-print"; - break; } if (!l10nId) { console.error( @@ -602,14 +596,10 @@ export const ContentAnalysis = { case Ci.nsIContentAnalysisRequest.eDroppedText: l10nId = "contentanalysis-slow-agent-dialog-body-dropped-text"; break; - case Ci.nsIContentAnalysisRequest.eOperationPrint: - l10nId = "contentanalysis-slow-agent-dialog-body-print"; - break; } if (!l10nId) { console.error( - "Unknown operationTypeForDisplay: ", - aResourceNameOrOperationType + "Unknown operationTypeForDisplay: " + aResourceNameOrOperationType ); return ""; } diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index 4c92988c9b90..bcfdf71b00d5 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -6,10 +6,8 @@ #include "mozilla/dom/CanonicalBrowsingContext.h" -#include "ContentAnalysis.h" #include "ErrorList.h" #include "mozilla/CheckedInt.h" -#include "mozilla/Components.h" #include "mozilla/ErrorResult.h" #include "mozilla/EventForwards.h" #include "mozilla/AsyncEventDispatcher.h" @@ -49,7 +47,6 @@ #include "nsFrameLoader.h" #include "nsFrameLoaderOwner.h" #include "nsGlobalWindowOuter.h" -#include "nsIContentAnalysis.h" #include "nsIWebBrowserChrome.h" #include "nsIXULRuntime.h" #include "nsNetUtil.h" @@ -671,9 +668,6 @@ CanonicalBrowsingContext::ReplaceLoadingSessionHistoryEntryForLoad( using PrintPromise = CanonicalBrowsingContext::PrintPromise; #ifdef NS_PRINTING -// Clients must call StaticCloneForPrintingCreated or -// NoStaticCloneForPrintingWillBeCreated before the underlying promise can -// resolve. class PrintListenerAdapter final : public nsIWebProgressListener { public: explicit PrintListenerAdapter(PrintPromise::Private* aPromise) @@ -684,14 +678,10 @@ class PrintListenerAdapter final : public nsIWebProgressListener { // NS_DECL_NSIWEBPROGRESSLISTENER NS_IMETHOD OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, uint32_t aStateFlags, nsresult aStatus) override { - MOZ_ASSERT(NS_IsMainThread()); if (aStateFlags & nsIWebProgressListener::STATE_STOP && aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT && mPromise) { - mPrintJobFinished = true; - if (mHaveSetBrowsingContext) { - mPromise->Resolve(mClonedStaticBrowsingContext, __func__); - mPromise = nullptr; - } + mPromise->Resolve(true, __func__); + mPromise = nullptr; } return NS_OK; } @@ -726,28 +716,10 @@ class PrintListenerAdapter final : public nsIWebProgressListener { return NS_OK; } - void StaticCloneForPrintingCreated( - MaybeDiscardedBrowsingContext&& aClonedStaticBrowsingContext) { - MOZ_ASSERT(NS_IsMainThread()); - mClonedStaticBrowsingContext = std::move(aClonedStaticBrowsingContext); - mHaveSetBrowsingContext = true; - if (mPrintJobFinished && mPromise) { - mPromise->Resolve(mClonedStaticBrowsingContext, __func__); - mPromise = nullptr; - } - } - - void NoStaticCloneForPrintingWillBeCreated() { - StaticCloneForPrintingCreated(nullptr); - } - private: ~PrintListenerAdapter() = default; RefPtr mPromise; - MaybeDiscardedBrowsingContext mClonedStaticBrowsingContext = nullptr; - bool mHaveSetBrowsingContext = false; - bool mPrintJobFinished = false; }; NS_IMPL_ISUPPORTS(PrintListenerAdapter, nsIWebProgressListener) @@ -763,9 +735,7 @@ already_AddRefed CanonicalBrowsingContext::PrintJS( Print(aPrintSettings) ->Then( GetCurrentSerialEventTarget(), __func__, - [promise](MaybeDiscardedBrowsingContext) { - promise->MaybeResolveWithUndefined(); - }, + [promise](bool) { promise->MaybeResolveWithUndefined(); }, [promise](nsresult aResult) { promise->MaybeReject(aResult); }); return promise.forget(); } @@ -775,72 +745,7 @@ RefPtr CanonicalBrowsingContext::Print( #ifndef NS_PRINTING return PrintPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__); #else -// Content analysis is not supported on non-Windows platforms. -# if defined(XP_WIN) - bool needContentAnalysis = false; - nsCOMPtr contentAnalysis = - mozilla::components::nsIContentAnalysis::Service(); - Unused << NS_WARN_IF(!contentAnalysis); - if (contentAnalysis) { - nsresult rv = contentAnalysis->GetIsActive(&needContentAnalysis); - Unused << NS_WARN_IF(NS_FAILED(rv)); - } - if (needContentAnalysis) { - auto done = MakeRefPtr(__func__); - contentanalysis::ContentAnalysis::PrintToPDFToDetermineIfPrintAllowed( - this, aPrintSettings) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [done, aPrintSettings = RefPtr{aPrintSettings}, - self = RefPtr{this}]( - contentanalysis::ContentAnalysis::PrintAllowedResult aResponse) - MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable { - if (aResponse.mAllowed) { - self->PrintWithNoContentAnalysis( - aPrintSettings, false, - aResponse.mCachedStaticDocumentBrowsingContext) - ->ChainTo(done.forget(), __func__); - } else { - // Since we are not doing the second print in this case, - // release the clone that is no longer needed. - self->ReleaseClonedPrint( - aResponse.mCachedStaticDocumentBrowsingContext); - done->Reject(NS_ERROR_CONTENT_BLOCKED, __func__); - } - }, - [done, self = RefPtr{this}]( - contentanalysis::ContentAnalysis::PrintAllowedError - aErrorResponse) MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA { - // Since we are not doing the second print in this case, release - // the clone that is no longer needed. - self->ReleaseClonedPrint( - aErrorResponse.mCachedStaticDocumentBrowsingContext); - done->Reject(aErrorResponse.mError, __func__); - }); - return done; - } -# endif - return PrintWithNoContentAnalysis(aPrintSettings, false, nullptr); -#endif -} -void CanonicalBrowsingContext::ReleaseClonedPrint( - const MaybeDiscardedBrowsingContext& aClonedStaticBrowsingContext) { -#ifdef NS_PRINTING - auto* browserParent = GetBrowserParent(); - if (NS_WARN_IF(!browserParent)) { - return; - } - Unused << browserParent->SendDestroyPrintClone(aClonedStaticBrowsingContext); -#endif -} - -RefPtr CanonicalBrowsingContext::PrintWithNoContentAnalysis( - nsIPrintSettings* aPrintSettings, bool aForceStaticDocument, - const MaybeDiscardedBrowsingContext& aCachedStaticDocument) { -#ifndef NS_PRINTING - return PrintPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__); -#else auto promise = MakeRefPtr(__func__); auto listener = MakeRefPtr(promise); if (IsInProcess()) { @@ -852,14 +757,12 @@ RefPtr CanonicalBrowsingContext::PrintWithNoContentAnalysis( } ErrorResult rv; - listener->NoStaticCloneForPrintingWillBeCreated(); outerWindow->Print(aPrintSettings, /* aRemotePrintJob = */ nullptr, listener, /* aDocShellToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No, nsGlobalWindowOuter::IsForWindowDotPrint::No, - /* aPrintPreviewCallback = */ nullptr, - /* aCachedBrowsingContext = */ nullptr, rv); + /* aPrintPreviewCallback = */ nullptr, rv); if (rv.Failed()) { promise->Reject(rv.StealNSResult(), __func__); } @@ -902,31 +805,12 @@ RefPtr CanonicalBrowsingContext::PrintWithNoContentAnalysis( printData.remotePrintJob() = browserParent->Manager()->SendPRemotePrintJobConstructor(remotePrintJob); - remotePrintJob->RegisterListener(listener); + if (listener) { + remotePrintJob->RegisterListener(listener); + } - if (!aCachedStaticDocument.IsNullOrDiscarded()) { - // There is no cloned static browsing context that - // SendPrintClonedPage() will return, so indicate this - // so listener can resolve its promise. - listener->NoStaticCloneForPrintingWillBeCreated(); - if (NS_WARN_IF(!browserParent->SendPrintClonedPage( - this, printData, aCachedStaticDocument))) { - promise->Reject(NS_ERROR_FAILURE, __func__); - } - } else { - RefPtr printPromise = - browserParent->SendPrint(this, printData, aForceStaticDocument); - printPromise->Then( - GetMainThreadSerialEventTarget(), __func__, - [listener](MaybeDiscardedBrowsingContext cachedStaticDocument) { - // promise will get resolved by the listener - listener->StaticCloneForPrintingCreated( - std::move(cachedStaticDocument)); - }, - [promise](ResponseRejectReason reason) { - NS_WARNING("SendPrint() failed"); - promise->Reject(NS_ERROR_FAILURE, __func__); - }); + if (NS_WARN_IF(!browserParent->SendPrint(this, printData))) { + promise->Reject(NS_ERROR_FAILURE, __func__); } return promise.forget(); #endif diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index ccbdf9ed9655..132c9f21578c 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -136,16 +136,11 @@ class CanonicalBrowsingContext final : public BrowsingContext { UniquePtr ReplaceLoadingSessionHistoryEntryForLoad( LoadingSessionHistoryInfo* aInfo, nsIChannel* aNewChannel); - using PrintPromise = - MozPromise; + using PrintPromise = MozPromise; MOZ_CAN_RUN_SCRIPT RefPtr Print(nsIPrintSettings*); MOZ_CAN_RUN_SCRIPT already_AddRefed PrintJS(nsIPrintSettings*, ErrorResult&); - MOZ_CAN_RUN_SCRIPT RefPtr PrintWithNoContentAnalysis( - nsIPrintSettings* aPrintSettings, bool aForceStaticDocument, - const MaybeDiscardedBrowsingContext& aClonedStaticBrowsingContext); - MOZ_CAN_RUN_SCRIPT void ReleaseClonedPrint( - const MaybeDiscardedBrowsingContext& aClonedStaticBrowsingContext); + // Call the given callback on all top-level descendant BrowsingContexts. // Return Callstate::Stop from the callback to stop calling further children. // diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 1e3fb93aa821..eca528f2588b 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -3388,8 +3388,7 @@ already_AddRefed nsFrameLoader::PrintPreview( /* aListener = */ nullptr, docShellToCloneInto, nsGlobalWindowOuter::IsPreview::Yes, nsGlobalWindowOuter::IsForWindowDotPrint::No, - [resolve](const PrintPreviewResultInfo& aInfo) { resolve(aInfo); }, - nullptr, rv); + [resolve](const PrintPreviewResultInfo& aInfo) { resolve(aInfo); }, rv); if (NS_WARN_IF(rv.Failed())) { promise->MaybeReject(std::move(rv)); } diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 7dcd265ca4a7..3dc63b83c25d 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -3752,7 +3752,7 @@ Nullable nsGlobalWindowInner::PrintPreview( /* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto, nsGlobalWindowOuter::IsPreview::Yes, nsGlobalWindowOuter::IsForWindowDotPrint::No, - /* aPrintPreviewCallback = */ nullptr, nullptr, aError), + /* aPrintPreviewCallback = */ nullptr, aError), aError, nullptr); } diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index c678a0a94150..7a7bd503daf0 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -5006,7 +5006,7 @@ void nsGlobalWindowOuter::PrintOuter(ErrorResult& aError) { const bool forPreview = !StaticPrefs::print_always_print_silent(); Print(nullptr, nullptr, nullptr, nullptr, IsPreview(forPreview), - IsForWindowDotPrint::Yes, nullptr, nullptr, aError); + IsForWindowDotPrint::Yes, nullptr, aError); #endif } @@ -5028,8 +5028,7 @@ Nullable nsGlobalWindowOuter::Print( nsIPrintSettings* aPrintSettings, RemotePrintJobChild* aRemotePrintJob, nsIWebProgressListener* aListener, nsIDocShell* aDocShellToCloneInto, IsPreview aIsPreview, IsForWindowDotPrint aForWindowDotPrint, - PrintPreviewResolver&& aPrintPreviewCallback, - RefPtr* aCachedBrowsingContext, ErrorResult& aError) { + PrintPreviewResolver&& aPrintPreviewCallback, ErrorResult& aError) { #ifdef NS_PRINTING nsCOMPtr printSettingsService = do_GetService("@mozilla.org/gfx/printsettings-service;1"); @@ -5065,36 +5064,16 @@ Nullable nsGlobalWindowOuter::Print( nsCOMPtr viewer; RefPtr bc; bool hasPrintCallbacks = false; - bool wasStaticDocument = docToPrint->IsStaticDocument(); - bool usingCachedBrowsingContext = false; - if (aCachedBrowsingContext && *aCachedBrowsingContext) { - MOZ_ASSERT(!wasStaticDocument, - "Why pass in non-empty aCachedBrowsingContext if original " - "document is already static?"); - if (!wasStaticDocument) { - // The passed in document is not a static clone and the caller passed in a - // static clone to reuse, so swap it in. - docToPrint = (*aCachedBrowsingContext)->GetDocument(); - MOZ_ASSERT(docToPrint); - MOZ_ASSERT(docToPrint->IsStaticDocument()); - wasStaticDocument = true; - usingCachedBrowsingContext = true; - } - } - if (wasStaticDocument) { + if (docToPrint->IsStaticDocument()) { if (aForWindowDotPrint == IsForWindowDotPrint::Yes) { aError.ThrowNotSupportedError( "Calling print() from a print preview is unsupported, did you intend " "to call printPreview() instead?"); return nullptr; } - if (usingCachedBrowsingContext) { - bc = docToPrint->GetBrowsingContext(); - } else { - // We're already a print preview window, just reuse our browsing context / - // content viewer. - bc = sourceBC; - } + // We're already a print preview window, just reuse our browsing context / + // content viewer. + bc = sourceBC; nsCOMPtr docShell = bc->GetDocShell(); if (!docShell) { aError.ThrowNotSupportedError("No docshell"); @@ -5136,10 +5115,6 @@ Nullable nsGlobalWindowOuter::Print( if (NS_WARN_IF(aError.Failed())) { return nullptr; } - if (aCachedBrowsingContext) { - MOZ_ASSERT(!*aCachedBrowsingContext); - *aCachedBrowsingContext = bc; - } } if (!bc) { aError.ThrowNotAllowedError("No browsing context"); @@ -5195,24 +5170,6 @@ Nullable nsGlobalWindowOuter::Print( "Content viewer didn't implement nsIWebBrowserPrint"); return nullptr; } - bool closeWindowAfterPrint; - if (wasStaticDocument) { - // Here the document was a static clone to begin with that this code did not - // create, so we should not clean it up. - // The exception is if we're using the passed-in aCachedBrowsingContext, in - // which case this is the second print with this static document clone that - // we created the first time through, and we are responsible for cleaning it - // up. - closeWindowAfterPrint = usingCachedBrowsingContext; - } else { - // In this case the document was not a static clone, so we made a static - // clone for printing purposes and must clean it up after the print is done. - // The exception is if aCachedBrowsingContext is non-NULL, meaning the - // caller is intending to print this document again, so we need to defer the - // cleanup until after the second print. - closeWindowAfterPrint = !aCachedBrowsingContext; - } - webBrowserPrint->SetCloseWindowAfterPrint(closeWindowAfterPrint); // For window.print(), we postpone making these calls until the round-trip to // the parent process (triggered by the OpenInternal call above) calls us diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index 3c26344c3d45..e9172f8f0534 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -580,8 +580,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, Print(nsIPrintSettings*, mozilla::layout::RemotePrintJobChild* aRemotePrintJob, nsIWebProgressListener*, nsIDocShell*, IsPreview, IsForWindowDotPrint, - PrintPreviewResolver&&, RefPtr*, - mozilla::ErrorResult&); + PrintPreviewResolver&&, mozilla::ErrorResult&); mozilla::dom::Selection* GetSelectionOuter(); already_AddRefed GetSelection() override; nsScreen* GetScreen(); diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index 3d1f399edb4f..bdd10fdcb285 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -2342,7 +2342,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview( /* aListener = */ nullptr, docShellToCloneInto, nsGlobalWindowOuter::IsPreview::Yes, nsGlobalWindowOuter::IsForWindowDotPrint::No, - std::move(aCallback), nullptr, IgnoreErrors()); + std::move(aCallback), IgnoreErrors()); #endif return IPC_OK(); } @@ -2359,9 +2359,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvExitPrintPreview() { return IPC_OK(); } -mozilla::ipc::IPCResult BrowserChild::CommonPrint( - const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData, - RefPtr* aCachedBrowsingContext) { +mozilla::ipc::IPCResult BrowserChild::RecvPrint( + const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData) { #ifdef NS_PRINTING if (NS_WARN_IF(aBc.IsNullOrDiscarded())) { return IPC_OK(); @@ -2390,12 +2389,12 @@ mozilla::ipc::IPCResult BrowserChild::CommonPrint( IgnoredErrorResult rv; RefPtr printJob = static_cast( aPrintData.remotePrintJob().AsChild()); - outerWindow->Print( - printSettings, printJob, - /* aListener = */ nullptr, - /* aWindowToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No, - nsGlobalWindowOuter::IsForWindowDotPrint::No, - /* aPrintPreviewCallback = */ nullptr, aCachedBrowsingContext, rv); + outerWindow->Print(printSettings, printJob, + /* aListener = */ nullptr, + /* aWindowToCloneInto = */ nullptr, + nsGlobalWindowOuter::IsPreview::No, + nsGlobalWindowOuter::IsForWindowDotPrint::No, + /* aPrintPreviewCallback = */ nullptr, rv); if (NS_WARN_IF(rv.Failed())) { return IPC_OK(); } @@ -2404,49 +2403,6 @@ mozilla::ipc::IPCResult BrowserChild::CommonPrint( return IPC_OK(); } -mozilla::ipc::IPCResult BrowserChild::RecvPrint( - const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData, - bool aReturnStaticClone, PrintResolver&& aResolve) { -#ifdef NS_PRINTING - RefPtr browsingContext; - auto result = CommonPrint(aBc, aPrintData, - aReturnStaticClone ? &browsingContext : nullptr); - aResolve(browsingContext); - return result; -#else - aResolve(nullptr); - return IPC_OK(); -#endif -} - -mozilla::ipc::IPCResult BrowserChild::RecvPrintClonedPage( - const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData, - const MaybeDiscardedBrowsingContext& aClonedBc) { -#ifdef NS_PRINTING - if (aClonedBc.IsNullOrDiscarded()) { - return IPC_OK(); - } - RefPtr clonedBc = aClonedBc.get(); - return CommonPrint(aBc, aPrintData, &clonedBc); -#else - return IPC_OK(); -#endif -} - -mozilla::ipc::IPCResult BrowserChild::RecvDestroyPrintClone( - const MaybeDiscardedBrowsingContext& aCachedPage) { -#ifdef NS_PRINTING - if (aCachedPage) { - RefPtr window = aCachedPage->GetDOMWindow(); - if (NS_WARN_IF(!window)) { - return IPC_OK(); - } - window->Close(); - } -#endif - return IPC_OK(); -} - mozilla::ipc::IPCResult BrowserChild::RecvUpdateNativeWindowHandle( const uintptr_t& aNewHandle) { #if defined(XP_WIN) && defined(ACCESSIBILITY) diff --git a/dom/ipc/BrowserChild.h b/dom/ipc/BrowserChild.h index 90cb7124763b..ddbf8f0b74fd 100644 --- a/dom/ipc/BrowserChild.h +++ b/dom/ipc/BrowserChild.h @@ -507,15 +507,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor, mozilla::ipc::IPCResult RecvExitPrintPreview(); MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvPrint( - const MaybeDiscardedBrowsingContext&, const PrintData&, bool, - PrintResolver&&); - - MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvPrintClonedPage( - const MaybeDiscardedBrowsingContext&, const PrintData&, - const MaybeDiscardedBrowsingContext&); - - mozilla::ipc::IPCResult RecvDestroyPrintClone( - const MaybeDiscardedBrowsingContext&); + const MaybeDiscardedBrowsingContext&, const PrintData&); mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle( const uintptr_t& aNewHandle); @@ -720,11 +712,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor, void InternalSetDocShellIsActive(bool aIsActive); - MOZ_CAN_RUN_SCRIPT - mozilla::ipc::IPCResult CommonPrint( - const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData, - RefPtr* aCachedBrowsingContext); - bool CreateRemoteLayerManager( mozilla::layers::PCompositorBridgeChild* aCompositorChild); diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 372a81b13934..727b579dd8ac 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -960,33 +960,8 @@ child: * * @param aBrowsingContext the browsing context to print. * @param aPrintData the serialized settings to print with - * @param aReturnStaticClone If the document in aBrowsingContext is not a static clone, whether - * to return the static document clone created. - * Note that if you call this with true but do not later call PrintClonedPage(), - * you must call DestroyPrintCache() to avoid leaks. */ - async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData, bool aReturnStaticClone) returns(MaybeDiscardedBrowsingContext staticCloneBrowsingContext); - - /** - * Tell the child to print the passed in static clone browsing context with the given settings. - * - * @param aBrowsingContext the browsing context to print. - * @param aPrintData the serialized settings to print with - * @param aStaticCloneBrowsingContext The static clone of aBrowsingContext that - * was created by an earlier call to Print(). This is the page that will actually be - * printed. - */ - async PrintClonedPage(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData, MaybeDiscardedBrowsingContext aStaticCloneBrowsingContext); - - /** - * Destroy the static document clone for printing, if present. See Print() for details. - * For callers' simplicity, it is safe to call this method even if aStaticCloneBrowsingContext - * is null or has already been discarded. - * - * @param aStaticCloneBrowsingContext The static clone that was created by - * an earlier call to Print(). - */ - async DestroyPrintClone(MaybeDiscardedBrowsingContext aStaticCloneBrowsingContext); + async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData); /** * Update the child with the tab's current top-level native window handle. diff --git a/dom/streams/TransformStream.cpp b/dom/streams/TransformStream.cpp index 3b78cabeea4a..e517ecda89a3 100644 --- a/dom/streams/TransformStream.cpp +++ b/dom/streams/TransformStream.cpp @@ -20,6 +20,14 @@ #include "mozilla/dom/TransformerBinding.h" #include "nsWrapperCache.h" +// XXX: GCC somehow does not allow attributes before lambda return types, while +// clang requires so. See also bug 1627007. +#ifdef __clang__ +# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA MOZ_CAN_RUN_SCRIPT_BOUNDARY +#else +# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA +#endif + namespace mozilla::dom { using namespace streams_abstract; diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 5ceec2159740..d1cf9bf2371a 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -449,7 +449,6 @@ class nsDocumentViewer final : public nsIDocumentViewer, #ifdef NS_PRINTING unsigned mClosingWhilePrinting : 1; - unsigned mCloseWindowAfterPrint : 1; # if NS_PRINT_PREVIEW RefPtr mPrintJob; @@ -521,7 +520,6 @@ nsDocumentViewer::nsDocumentViewer() mInPermitUnloadPrompt(false), #ifdef NS_PRINTING mClosingWhilePrinting(false), - mCloseWindowAfterPrint(false), #endif // NS_PRINTING mReloadEncodingSource(kCharsetUninitialized), mReloadEncoding(nullptr), @@ -3141,20 +3139,6 @@ nsDocumentViewer::GetDoingPrintPreview(bool* aDoingPrintPreview) { return NS_OK; } -NS_IMETHODIMP -nsDocumentViewer::GetCloseWindowAfterPrint(bool* aCloseWindowAfterPrint) { - NS_ENSURE_ARG_POINTER(aCloseWindowAfterPrint); - - *aCloseWindowAfterPrint = mCloseWindowAfterPrint; - return NS_OK; -} - -NS_IMETHODIMP -nsDocumentViewer::SetCloseWindowAfterPrint(bool aCloseWindowAfterPrint) { - mCloseWindowAfterPrint = aCloseWindowAfterPrint; - return NS_OK; -} - NS_IMETHODIMP nsDocumentViewer::ExitPrintPreview() { NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE); @@ -3319,15 +3303,13 @@ void nsDocumentViewer::OnDonePrinting() { // We are done printing, now clean up. // - // If the original document to print was not a static clone, we opened a new - // window and are responsible for cleaning up the whole or window - // (see the OPEN_PRINT_BROWSER code, specifically - // handleStaticCloneCreatedForPrint()), so gotta run window.close(), which - // will take care of this. + // For non-print-preview jobs, we are actually responsible for cleaning up + // our whole or window (see the OPEN_PRINT_BROWSER code), so gotta + // run window.close(), which will take care of this. // - // Otherwise the front-end code is responsible for cleaning the UI. - bool closeWindowAfterPrint = GetCloseWindowAfterPrint(); - if (closeWindowAfterPrint) { + // For print preview jobs the front-end code is responsible for cleaning the + // UI. + if (!printJob->CreatedForPrintPreview()) { if (mContainer) { if (nsCOMPtr win = mContainer->GetWindow()) { win->Close(); diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index 3be46cf5a824..b4b0316a3ac3 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -1031,12 +1031,4 @@ # define MOZ_EMPTY_BASES #endif -// XXX: GCC somehow does not allow attributes before lambda return types, while -// clang requires so. See also bug 1627007. -#ifdef __clang__ -# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA MOZ_CAN_RUN_SCRIPT_BOUNDARY -#else -# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA -#endif - #endif /* mozilla_Attributes_h */ diff --git a/toolkit/components/browser/nsIWebBrowserPrint.idl b/toolkit/components/browser/nsIWebBrowserPrint.idl index 2b5d7669bcb7..5a900b7b6583 100644 --- a/toolkit/components/browser/nsIWebBrowserPrint.idl +++ b/toolkit/components/browser/nsIWebBrowserPrint.idl @@ -30,7 +30,7 @@ native PrintPreviewResolver(std::function # define SECURITY_WIN32 1 # include -# include "mozilla/NativeNt.h" # include "mozilla/WinDllServices.h" #endif // XP_WIN @@ -119,11 +114,6 @@ nsIContentAnalysisAcknowledgement::FinalAction ConvertResult( } // anonymous namespace namespace mozilla::contentanalysis { -ContentAnalysisRequest::~ContentAnalysisRequest() { -#ifdef XP_WIN - CloseHandle(mPrintDataHandle); -#endif -} NS_IMETHODIMP ContentAnalysisRequest::GetAnalysisType(AnalysisType* aAnalysisType) { @@ -143,34 +133,6 @@ ContentAnalysisRequest::GetFilePath(nsAString& aFilePath) { return NS_OK; } -NS_IMETHODIMP -ContentAnalysisRequest::GetPrintDataHandle(uint64_t* aPrintDataHandle) { -#ifdef XP_WIN - uintptr_t printDataHandle = reinterpret_cast(mPrintDataHandle); - uint64_t printDataValue = static_cast(printDataHandle); - *aPrintDataHandle = printDataValue; - return NS_OK; -#else - return NS_ERROR_NOT_IMPLEMENTED; -#endif -} - -NS_IMETHODIMP -ContentAnalysisRequest::GetPrinterName(nsAString& aPrinterName) { - aPrinterName = mPrinterName; - return NS_OK; -} - -NS_IMETHODIMP -ContentAnalysisRequest::GetPrintDataSize(uint64_t* aPrintDataSize) { -#ifdef XP_WIN - *aPrintDataSize = mPrintDataSize; - return NS_OK; -#else - return NS_ERROR_NOT_IMPLEMENTED; -#endif -} - NS_IMETHODIMP ContentAnalysisRequest::GetUrl(nsIURI** aUrl) { NS_ENSURE_ARG_POINTER(aUrl); @@ -272,8 +234,6 @@ ContentAnalysisRequest::ContentAnalysisRequest( mUrl(std::move(aUrl)), mSha256Digest(std::move(aSha256Digest)), mWindowGlobalParent(aWindowGlobalParent) { - MOZ_ASSERT(aAnalysisType != AnalysisType::ePrint, - "Print should use other ContentAnalysisRequest constructor!"); if (aStringIsFilePath) { mFilePath = std::move(aString); } else { @@ -291,32 +251,6 @@ ContentAnalysisRequest::ContentAnalysisRequest( mRequestToken = GenerateRequestToken(); } -ContentAnalysisRequest::ContentAnalysisRequest( - const nsTArray aPrintData, nsCOMPtr aUrl, - nsString aPrinterName, dom::WindowGlobalParent* aWindowGlobalParent) - : mAnalysisType(AnalysisType::ePrint), - mUrl(std::move(aUrl)), - mPrinterName(std::move(aPrinterName)), - mWindowGlobalParent(aWindowGlobalParent) { -#ifdef XP_WIN - LARGE_INTEGER dataContentLength; - dataContentLength.QuadPart = static_cast(aPrintData.Length()); - mPrintDataHandle = ::CreateFileMappingW( - INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, dataContentLength.HighPart, - dataContentLength.LowPart, nullptr); - if (mPrintDataHandle) { - mozilla::nt::AutoMappedView view(mPrintDataHandle, FILE_MAP_ALL_ACCESS); - memcpy(view.as(), aPrintData.Elements(), aPrintData.Length()); - mPrintDataSize = aPrintData.Length(); - } -#else - MOZ_ASSERT_UNREACHABLE( - "Content Analysis is not supported on non-Windows platforms"); -#endif - mOperationTypeForDisplay = OperationType::eOperationPrint; - mRequestToken = GenerateRequestToken(); -} - nsresult ContentAnalysisRequest::GetFileDigest(const nsAString& aFilePath, nsCString& aDigestString) { MOZ_DIAGNOSTIC_ASSERT( @@ -432,44 +366,22 @@ static nsresult ConvertToProtobuf( requestData->set_digest(sha256Digest.get()); } - if (analysisType == nsIContentAnalysisRequest::AnalysisType::ePrint) { -#if XP_WIN - uint64_t printDataHandle; - MOZ_TRY(aIn->GetPrintDataHandle(&printDataHandle)); - if (!printDataHandle) { - return NS_ERROR_OUT_OF_MEMORY; + nsString filePath; + rv = aIn->GetFilePath(filePath); + NS_ENSURE_SUCCESS(rv, rv); + if (!filePath.IsEmpty()) { + std::string filePathStr = NS_ConvertUTF16toUTF8(filePath).get(); + aOut->set_file_path(filePathStr); + auto filename = filePathStr.substr(filePathStr.find_last_of("/\\") + 1); + if (!filename.empty()) { + requestData->set_filename(filename); } - aOut->mutable_print_data()->set_handle(printDataHandle); - - uint64_t printDataSize; - MOZ_TRY(aIn->GetPrintDataSize(&printDataSize)); - aOut->mutable_print_data()->set_size(printDataSize); - - nsString printerName; - MOZ_TRY(aIn->GetPrinterName(printerName)); - requestData->mutable_print_metadata()->set_printer_name( - NS_ConvertUTF16toUTF8(printerName).get()); -#else - return NS_ERROR_NOT_IMPLEMENTED; -#endif } else { - nsString filePath; - rv = aIn->GetFilePath(filePath); + nsString textContent; + rv = aIn->GetTextContent(textContent); NS_ENSURE_SUCCESS(rv, rv); - if (!filePath.IsEmpty()) { - std::string filePathStr = NS_ConvertUTF16toUTF8(filePath).get(); - aOut->set_file_path(filePathStr); - auto filename = filePathStr.substr(filePathStr.find_last_of("/\\") + 1); - if (!filename.empty()) { - requestData->set_filename(filename); - } - } else { - nsString textContent; - rv = aIn->GetTextContent(textContent); - NS_ENSURE_SUCCESS(rv, rv); - MOZ_ASSERT(!textContent.IsEmpty()); - aOut->set_text_content(NS_ConvertUTF16toUTF8(textContent).get()); - } + MOZ_ASSERT(!textContent.IsEmpty()); + aOut->set_text_content(NS_ConvertUTF16toUTF8(textContent).get()); } #ifdef XP_WIN @@ -1306,9 +1218,7 @@ void ContentAnalysis::IssueResponse(RefPtr& response) { LOGD("Content analysis resolving response promise for token %s", responseRequestToken.get()); - nsIContentAnalysisResponse::Action action; - DebugOnly rv = response->GetAction(&action); - MOZ_ASSERT(NS_SUCCEEDED(rv)); + nsIContentAnalysisResponse::Action action = response->GetAction(); nsCOMPtr obsServ = mozilla::services::GetObserverService(); if (action == nsIContentAnalysisResponse::Action::eWarn) { @@ -1470,9 +1380,7 @@ ContentAnalysis::RespondToWarnDialog(const nsACString& aRequestToken, return; } entry->mResponse->ResolveWarnAction(aAllowContent); - nsIContentAnalysisResponse::Action action; - DebugOnly rv = entry->mResponse->GetAction(&action); - MOZ_ASSERT(NS_SUCCEEDED(rv)); + auto action = entry->mResponse->GetAction(); if (entry->mCallbackData.AutoAcknowledge()) { RefPtr acknowledgement = new ContentAnalysisAcknowledgement( @@ -1497,181 +1405,6 @@ ContentAnalysis::RespondToWarnDialog(const nsACString& aRequestToken, return NS_OK; } -#if defined(XP_WIN) -RefPtr -ContentAnalysis::PrintToPDFToDetermineIfPrintAllowed( - dom::CanonicalBrowsingContext* aBrowsingContext, - nsIPrintSettings* aPrintSettings) { - // Note that the IsChrome() check here excludes a few - // common about pages like about:config, about:preferences, - // and about:support, but other about: pages may still - // go through content analysis. - if (aBrowsingContext->IsChrome()) { - return PrintAllowedPromise::CreateAndResolve(PrintAllowedResult(true), - __func__); - } - nsCOMPtr contentAnalysisPrintSettings; - if (NS_WARN_IF(NS_FAILED(aPrintSettings->Clone( - getter_AddRefs(contentAnalysisPrintSettings)))) || - NS_WARN_IF(!aBrowsingContext->GetCurrentWindowGlobal())) { - return PrintAllowedPromise::CreateAndReject( - PrintAllowedError(NS_ERROR_FAILURE), __func__); - } - contentAnalysisPrintSettings->SetOutputDestination( - nsIPrintSettings::OutputDestinationType::kOutputDestinationStream); - contentAnalysisPrintSettings->SetOutputFormat( - nsIPrintSettings::kOutputFormatPDF); - nsCOMPtr storageStream = - do_CreateInstance("@mozilla.org/storagestream;1"); - if (!storageStream) { - return PrintAllowedPromise::CreateAndReject( - PrintAllowedError(NS_ERROR_FAILURE), __func__); - } - // Use segment size of 512K - nsresult rv = storageStream->Init(0x80000, UINT32_MAX); - if (NS_WARN_IF(NS_FAILED(rv))) { - return PrintAllowedPromise::CreateAndReject(PrintAllowedError(rv), - __func__); - } - - nsCOMPtr outputStream; - storageStream->QueryInterface(NS_GET_IID(nsIOutputStream), - getter_AddRefs(outputStream)); - MOZ_ASSERT(outputStream); - - contentAnalysisPrintSettings->SetOutputStream(outputStream.get()); - RefPtr browsingContext = aBrowsingContext; - auto promise = MakeRefPtr(__func__); - nsCOMPtr finalPrintSettings(aPrintSettings); - aBrowsingContext - ->PrintWithNoContentAnalysis(contentAnalysisPrintSettings, true, nullptr) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [browsingContext, contentAnalysisPrintSettings, finalPrintSettings, - promise]( - dom::MaybeDiscardedBrowsingContext cachedStaticBrowsingContext) - MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable { - nsCOMPtr outputStream; - contentAnalysisPrintSettings->GetOutputStream( - getter_AddRefs(outputStream)); - nsCOMPtr storageStream = - do_QueryInterface(outputStream); - MOZ_ASSERT(storageStream); - nsTArray printData; - uint32_t length = 0; - storageStream->GetLength(&length); - if (!printData.SetLength(length, fallible)) { - promise->Reject( - PrintAllowedError(NS_ERROR_OUT_OF_MEMORY, - cachedStaticBrowsingContext), - __func__); - return; - } - nsCOMPtr inputStream; - nsresult rv = storageStream->NewInputStream( - 0, getter_AddRefs(inputStream)); - if (NS_FAILED(rv)) { - promise->Reject( - PrintAllowedError(rv, cachedStaticBrowsingContext), - __func__); - return; - } - uint32_t currentPosition = 0; - while (currentPosition < length) { - uint32_t elementsRead = 0; - // Make sure the reinterpret_cast<> below is safe - static_assert(std::is_trivially_assignable_v< - decltype(*printData.Elements()), char>); - rv = inputStream->Read( - reinterpret_cast(printData.Elements()) + - currentPosition, - length - currentPosition, &elementsRead); - if (NS_WARN_IF(NS_FAILED(rv) || !elementsRead)) { - promise->Reject( - PrintAllowedError(NS_FAILED(rv) ? rv : NS_ERROR_FAILURE, - cachedStaticBrowsingContext), - __func__); - return; - } - currentPosition += elementsRead; - } - - nsString printerName; - rv = contentAnalysisPrintSettings->GetPrinterName(printerName); - if (NS_WARN_IF(NS_FAILED(rv))) { - promise->Reject( - PrintAllowedError(rv, cachedStaticBrowsingContext), - __func__); - return; - } - - auto* windowParent = browsingContext->GetCurrentWindowGlobal(); - if (!windowParent) { - // The print window may have been closed by the user by now. - // Cancel the print. - promise->Reject( - PrintAllowedError(NS_ERROR_ABORT, - cachedStaticBrowsingContext), - __func__); - return; - } - nsCOMPtr uri = windowParent->GetDocumentURI(); - nsCOMPtr contentAnalysisRequest = - new contentanalysis::ContentAnalysisRequest( - std::move(printData), std::move(uri), - std::move(printerName), windowParent); - auto callback = - MakeRefPtr( - [browsingContext, cachedStaticBrowsingContext, promise, - finalPrintSettings = std::move(finalPrintSettings)]( - nsIContentAnalysisResponse* aResponse) - MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable { - bool shouldAllow = false; - DebugOnly rv = - aResponse->GetShouldAllowContent( - &shouldAllow); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - promise->Resolve( - PrintAllowedResult( - shouldAllow, cachedStaticBrowsingContext), - __func__); - }, - [promise, - cachedStaticBrowsingContext](nsresult aError) { - promise->Reject( - PrintAllowedError(aError, - cachedStaticBrowsingContext), - __func__); - }); - nsCOMPtr contentAnalysis = - mozilla::components::nsIContentAnalysis::Service(); - if (NS_WARN_IF(!contentAnalysis)) { - promise->Reject( - PrintAllowedError(rv, cachedStaticBrowsingContext), - __func__); - } else { - bool isActive = false; - nsresult rv = contentAnalysis->GetIsActive(&isActive); - // Should not be called if content analysis is not active - MOZ_ASSERT(isActive); - Unused << NS_WARN_IF(NS_FAILED(rv)); - rv = contentAnalysis->AnalyzeContentRequestCallback( - contentAnalysisRequest, /* aAutoAcknowledge */ true, - callback); - if (NS_WARN_IF(NS_FAILED(rv))) { - promise->Reject( - PrintAllowedError(rv, cachedStaticBrowsingContext), - __func__); - } - } - }, - [promise](nsresult aError) { - promise->Reject(PrintAllowedError(aError), __func__); - }); - return promise; -} -#endif - NS_IMETHODIMP ContentAnalysisResponse::Acknowledge( nsIContentAnalysisAcknowledgement* aAcknowledgement) { diff --git a/toolkit/components/contentanalysis/ContentAnalysis.h b/toolkit/components/contentanalysis/ContentAnalysis.h index f2545624fd0f..a99bbe80c37d 100644 --- a/toolkit/components/contentanalysis/ContentAnalysis.h +++ b/toolkit/components/contentanalysis/ContentAnalysis.h @@ -8,8 +8,6 @@ #include "mozilla/DataMutex.h" #include "mozilla/MozPromise.h" -#include "mozilla/dom/BrowsingContext.h" -#include "mozilla/dom/MaybeDiscarded.h" #include "mozilla/dom/Promise.h" #include "nsIContentAnalysis.h" #include "nsProxyRelease.h" @@ -20,16 +18,10 @@ #include #include -#ifdef XP_WIN -# include -#endif // XP_WIN - class nsIPrincipal; -class nsIPrintSettings; class ContentAnalysisTest; namespace mozilla::dom { -class CanonicalBrowsingContext; class DataTransfer; class WindowGlobalParent; } // namespace mozilla::dom @@ -72,15 +64,11 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest { bool aStringIsFilePath, nsCString aSha256Digest, nsCOMPtr aUrl, OperationType aOperationType, dom::WindowGlobalParent* aWindowGlobalParent); - ContentAnalysisRequest(const nsTArray aPrintData, - nsCOMPtr aUrl, nsString aPrinterName, - dom::WindowGlobalParent* aWindowGlobalParent); static nsresult GetFileDigest(const nsAString& aFilePath, nsCString& aDigestString); private: - ~ContentAnalysisRequest(); - + ~ContentAnalysisRequest() = default; // Remove unneeded copy constructor/assignment ContentAnalysisRequest(const ContentAnalysisRequest&) = delete; ContentAnalysisRequest& operator=(ContentAnalysisRequest&) = delete; @@ -117,16 +105,7 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest { // OPERATION_CUSTOMDISPLAYSTRING nsString mOperationDisplayString; - // The name of the printer being printed to - nsString mPrinterName; - RefPtr mWindowGlobalParent; -#ifdef XP_WIN - // The printed data to analyze, in PDF format - HANDLE mPrintDataHandle = 0; - // The size of the printed data in mPrintDataHandle - uint64_t mPrintDataSize = 0; -#endif friend class ::ContentAnalysisTest; }; @@ -149,39 +128,6 @@ class ContentAnalysis final : public nsIContentAnalysis { nsCString GetUserActionId(); void SetLastResult(nsresult aLastResult) { mLastResult = aLastResult; } - struct PrintAllowedResult final { - bool mAllowed; - dom::MaybeDiscarded - mCachedStaticDocumentBrowsingContext; - PrintAllowedResult(bool aAllowed, dom::MaybeDiscarded - aCachedStaticDocumentBrowsingContext) - : mAllowed(aAllowed), - mCachedStaticDocumentBrowsingContext( - aCachedStaticDocumentBrowsingContext) {} - explicit PrintAllowedResult(bool aAllowed) - : PrintAllowedResult(aAllowed, dom::MaybeDiscardedBrowsingContext()) {} - }; - struct PrintAllowedError final { - nsresult mError; - dom::MaybeDiscarded - mCachedStaticDocumentBrowsingContext; - PrintAllowedError(nsresult aError, dom::MaybeDiscarded - aCachedStaticDocumentBrowsingContext) - : mError(aError), - mCachedStaticDocumentBrowsingContext( - aCachedStaticDocumentBrowsingContext) {} - explicit PrintAllowedError(nsresult aError) - : PrintAllowedError(aError, dom::MaybeDiscardedBrowsingContext()) {} - }; - using PrintAllowedPromise = - MozPromise; -#if defined(XP_WIN) - MOZ_CAN_RUN_SCRIPT static RefPtr - PrintToPDFToDetermineIfPrintAllowed( - dom::CanonicalBrowsingContext* aBrowsingContext, - nsIPrintSettings* aPrintSettings); -#endif // defined(XP_WIN) - private: ~ContentAnalysis(); // Remove unneeded copy constructor/assignment diff --git a/toolkit/components/contentanalysis/ContentAnalysisIPCTypes.h b/toolkit/components/contentanalysis/ContentAnalysisIPCTypes.h index a5540362570c..f6bfd2fcb5a2 100644 --- a/toolkit/components/contentanalysis/ContentAnalysisIPCTypes.h +++ b/toolkit/components/contentanalysis/ContentAnalysisIPCTypes.h @@ -87,11 +87,7 @@ class ContentAnalysisResult : public nsIContentAnalysisResult { static RefPtr FromContentAnalysisResponse( nsIContentAnalysisResponse* aResponse) { - bool shouldAllowContent = false; - DebugOnly rv = - aResponse->GetShouldAllowContent(&shouldAllowContent); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - if (shouldAllowContent) { + if (aResponse->GetShouldAllowContent()) { return FromAction(nsIContentAnalysisResponse::Action::eAllow); } else { return FromAction(nsIContentAnalysisResponse::Action::eBlock); diff --git a/toolkit/components/contentanalysis/components.conf b/toolkit/components/contentanalysis/components.conf index 1683ef99d752..82236cb1b920 100644 --- a/toolkit/components/contentanalysis/components.conf +++ b/toolkit/components/contentanalysis/components.conf @@ -11,6 +11,5 @@ Classes = [ 'contract_ids': ['@mozilla.org/contentanalysis;1'], 'type': 'mozilla::contentanalysis::ContentAnalysis', 'headers': ['/toolkit/components/contentanalysis/ContentAnalysis.h'], - 'overridable': True, }, ] diff --git a/toolkit/components/contentanalysis/nsIContentAnalysis.idl b/toolkit/components/contentanalysis/nsIContentAnalysis.idl index 63ac8d12fbfe..3bea9eb808f3 100644 --- a/toolkit/components/contentanalysis/nsIContentAnalysis.idl +++ b/toolkit/components/contentanalysis/nsIContentAnalysis.idl @@ -36,7 +36,7 @@ interface nsIContentAnalysisAcknowledgement : nsISupports readonly attribute nsIContentAnalysisAcknowledgement_FinalAction finalAction; }; -[scriptable, uuid(89088c61-15f6-4ace-a880-a1b5ea47ca66)] +[scriptable, builtinclass, uuid(89088c61-15f6-4ace-a880-a1b5ea47ca66)] interface nsIContentAnalysisResponse : nsISupports { // These values must stay synchronized with ContentAnalysisResponse @@ -59,11 +59,11 @@ interface nsIContentAnalysisResponse : nsISupports eErrorOther = 3, }; - readonly attribute nsIContentAnalysisResponse_Action action; - readonly attribute boolean shouldAllowContent; + [infallible] readonly attribute nsIContentAnalysisResponse_Action action; + [infallible] readonly attribute boolean shouldAllowContent; // If action is eCanceled, this is the error explaining why the request was canceled, // or eUserInitiated if the user canceled it. - readonly attribute nsIContentAnalysisResponse_CancelError cancelError; + [infallible] readonly attribute nsIContentAnalysisResponse_CancelError cancelError; // Identifier for the corresponding nsIContentAnalysisRequest readonly attribute ACString requestToken; @@ -131,7 +131,6 @@ interface nsIContentAnalysisRequest : nsISupports eCustomDisplayString = 0, eClipboard = 1, eDroppedText = 2, - eOperationPrint = 3, }; readonly attribute nsIContentAnalysisRequest_OperationType operationTypeForDisplay; readonly attribute AString operationDisplayString; @@ -142,15 +141,6 @@ interface nsIContentAnalysisRequest : nsISupports // Name of file to analyze. Only one of textContent or filePath is defined. readonly attribute AString filePath; - // HANDLE to the printed data in PDF format. - readonly attribute unsigned long long printDataHandle; - - // Size of the data stored in printDataHandle. - readonly attribute unsigned long long printDataSize; - - // Name of the printer being printed to. - readonly attribute AString printerName; - // The URL containing the file download/upload or to which web content is // being uploaded. readonly attribute nsIURI url; @@ -195,7 +185,7 @@ interface nsIContentAnalysisDiagnosticInfo : nsISupports [infallible] readonly attribute long long requestCount; }; -[scriptable, uuid(61497587-2bba-4a88-acd3-3fbb2cedf163)] +[scriptable, builtinclass, uuid(61497587-2bba-4a88-acd3-3fbb2cedf163)] interface nsIContentAnalysis : nsISupports { /** diff --git a/toolkit/components/contentanalysis/tests/browser/browser.toml b/toolkit/components/contentanalysis/tests/browser/browser.toml index bdbf35059324..0e210902996d 100644 --- a/toolkit/components/contentanalysis/tests/browser/browser.toml +++ b/toolkit/components/contentanalysis/tests/browser/browser.toml @@ -1,20 +1,3 @@ [DEFAULT] -run-if = ["os == 'win'"] -support-files = [ - "head.js", -] ["browser_content_analysis_policies.js"] - -["browser_print_changing_page_content_analysis.js"] -support-files = [ - "!/toolkit/components/printing/tests/head.js", - "changing_page_for_print.html", -] - -["browser_print_content_analysis.js"] -support-files = [ - "!/toolkit/components/printing/tests/head.js", - "!/toolkit/components/printing/tests/longerArticle.html", - "!/toolkit/components/printing/tests/simplifyArticleSample.html", -] diff --git a/toolkit/components/contentanalysis/tests/browser/browser_print_changing_page_content_analysis.js b/toolkit/components/contentanalysis/tests/browser/browser_print_changing_page_content_analysis.js deleted file mode 100644 index 72a7dcbb9107..000000000000 --- a/toolkit/components/contentanalysis/tests/browser/browser_print_changing_page_content_analysis.js +++ /dev/null @@ -1,339 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/toolkit/components/printing/tests/head.js", - this -); - -const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService( - Ci.nsIPrintSettingsService -); - -let mockCA = { - isActive: true, - mightBeActive: true, - errorValue: undefined, - - setupForTest(shouldAllowRequest) { - this.shouldAllowRequest = shouldAllowRequest; - this.errorValue = undefined; - this.calls = []; - }, - - setupForTestWithError(errorValue) { - this.errorValue = errorValue; - this.calls = []; - }, - - getAction() { - if (this.shouldAllowRequest === undefined) { - this.shouldAllowRequest = true; - } - return this.shouldAllowRequest - ? Ci.nsIContentAnalysisResponse.eAllow - : Ci.nsIContentAnalysisResponse.eBlock; - }, - - // nsIContentAnalysis methods - async analyzeContentRequest(request, _autoAcknowledge) { - info( - "Mock ContentAnalysis service: analyzeContentRequest, this.shouldAllowRequest=" + - this.shouldAllowRequest + - ", this.errorValue=" + - this.errorValue - ); - this.calls.push(request); - if (this.errorValue) { - throw this.errorValue; - } - // Use setTimeout to simulate an async activity - await new Promise(res => setTimeout(res, 0)); - return makeContentAnalysisResponse(this.getAction(), request.requestToken); - }, - - analyzeContentRequestCallback(request, autoAcknowledge, callback) { - info( - "Mock ContentAnalysis service: analyzeContentRequestCallback, this.shouldAllowRequest=" + - this.shouldAllowRequest + - ", this.errorValue=" + - this.errorValue - ); - this.calls.push(request); - if (this.errorValue) { - throw this.errorValue; - } - let response = makeContentAnalysisResponse( - this.getAction(), - request.requestToken - ); - // Use setTimeout to simulate an async activity - setTimeout(() => { - callback.contentResult(response); - }, 0); - }, -}; - -add_setup(async function test_setup() { - mockCA = mockContentAnalysisService(mockCA); -}); - -const TEST_PAGE_URL = PrintHelper.getTestPageUrlHTTPS( - "changing_page_for_print.html" -); - -function addUniqueSuffix(prefix) { - return `${prefix}-${Services.uuid - .generateUUID() - .toString() - .slice(1, -1)}.pdf`; -} - -async function printToDestination(aBrowser, aDestination) { - let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile); - let fileName = addUniqueSuffix(`printDestinationTest-${aDestination}`); - let filePath = PathUtils.join(tmpDir.path, fileName); - - info(`Printing to ${filePath}`); - - let settings = PSSVC.createNewPrintSettings(); - settings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF; - settings.outputDestination = aDestination; - - settings.headerStrCenter = ""; - settings.headerStrLeft = ""; - settings.headerStrRight = ""; - settings.footerStrCenter = ""; - settings.footerStrLeft = ""; - settings.footerStrRight = ""; - - settings.unwriteableMarginTop = 1; /* Just to ensure settings are respected on both */ - let outStream = null; - if (aDestination == Ci.nsIPrintSettings.kOutputDestinationFile) { - settings.toFileName = PathUtils.join(tmpDir.path, fileName); - } else { - is(aDestination, Ci.nsIPrintSettings.kOutputDestinationStream); - outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance( - Ci.nsIFileOutputStream - ); - let tmpFile = tmpDir.clone(); - tmpFile.append(fileName); - outStream.init(tmpFile, -1, 0o666, 0); - settings.outputStream = outStream; - } - - await aBrowser.browsingContext.print(settings); - - return filePath; -} - -function assertContentAnalysisRequest(request) { - is(request.url.spec, TEST_PAGE_URL, "request has correct URL"); - is( - request.analysisType, - Ci.nsIContentAnalysisRequest.ePrint, - "request has print analysisType" - ); - is( - request.operationTypeForDisplay, - Ci.nsIContentAnalysisRequest.eOperationPrint, - "request has print operationTypeForDisplay" - ); - is(request.textContent, "", "request textContent should be empty"); - is(request.filePath, "", "request filePath should be empty"); - isnot(request.printDataHandle, 0, "request printDataHandle should not be 0"); - isnot(request.printDataSize, 0, "request printDataSize should not be 0"); - ok(!!request.requestToken.length, "request requestToken should not be empty"); -} - -add_task( - async function testPrintToStreamWithContentAnalysisActiveAndAllowing() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(true); - - let filePath = await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - - // This effectively tests that the PDF content sent to Content Analysis - // and the content that is actually printed matches. This is necessary - // because a previous iteration of the Content Analysis code didn't use - // a static Document clone for this and so the content would differ. (since - // the .html file in question adds content to the page when print events - // happen) - await waitForFileToAlmostMatchSize( - filePath, - mockCA.calls[0].printDataSize - ); - - await IOUtils.remove(filePath); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task( - async function testPrintToStreamWithContentAnalysisActiveAndBlocking() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(false); - - try { - await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - ok(false, "Content analysis should make this fail to print"); - } catch (e) { - ok( - /NS_ERROR_CONTENT_BLOCKED/.test(e.toString()), - "Got content blocked error" - ); - } - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task(async function testPrintToStreamWithContentAnalysisReturningError() { - await PrintHelper.withTestPage( - async helper => { - expectUncaughtException(); - mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE); - - try { - await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - ok(false, "Content analysis should make this fail to print"); - } catch (e) { - ok( - /NS_ERROR_NOT_AVAILABLE/.test(e.toString()), - "Error in mock CA was propagated out" - ); - } - is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis"); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); -}); - -add_task(async function testPrintThroughDialogWithContentAnalysisActive() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(true); - - let fileName = addUniqueSuffix(`printDialogTest`); - let file = helper.mockFilePicker(fileName); - info(`Printing to ${file.path}`); - await helper.startPrint(); - await helper.assertPrintToFile(file, () => { - EventUtils.sendKey("return", helper.win); - }); - - is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis"); - assertContentAnalysisRequest(mockCA.calls[0]); - - await waitForFileToAlmostMatchSize( - file.path, - mockCA.calls[0].printDataSize - ); - }, - TEST_PAGE_URL, - true - ); -}); - -add_task( - async function testPrintThroughDialogWithContentAnalysisActiveAndBlocking() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(false); - - await helper.startPrint(); - let fileName = addUniqueSuffix(`printDialogTest`); - let file = helper.mockFilePicker(fileName); - info(`Printing to ${file.path}`); - try { - await helper.assertPrintToFile(file, () => { - EventUtils.sendKey("return", helper.win); - }); - } catch (e) { - ok( - /Wait for target file to get created/.test(e.toString()), - "Target file should not get created" - ); - } - ok(!file.exists(), "File should not exist"); - - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task( - async function testPrintThroughDialogWithContentAnalysisReturningError() { - await PrintHelper.withTestPage( - async helper => { - expectUncaughtException(); - mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE); - - await helper.startPrint(); - let fileName = addUniqueSuffix(`printDialogTest`); - let file = helper.mockFilePicker(fileName); - info(`Printing to ${file.path}`); - try { - await helper.assertPrintToFile(file, () => { - EventUtils.sendKey("return", helper.win); - }); - } catch (e) { - ok( - /Wait for target file to get created/.test(e.toString()), - "Target file should not get created" - ); - } - ok(!file.exists(), "File should not exist"); - - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); - } -); diff --git a/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js b/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js deleted file mode 100644 index 9b4c0ffa6090..000000000000 --- a/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js +++ /dev/null @@ -1,390 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/toolkit/components/printing/tests/head.js", - this -); - -const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService( - Ci.nsIPrintSettingsService -); - -let mockCA = { - isActive: true, - mightBeActive: true, - errorValue: undefined, - - setupForTest(shouldAllowRequest) { - this.shouldAllowRequest = shouldAllowRequest; - this.errorValue = undefined; - this.calls = []; - }, - - setupForTestWithError(errorValue) { - this.errorValue = errorValue; - this.calls = []; - }, - - clearCalls() { - this.calls = []; - }, - - getAction() { - if (this.shouldAllowRequest === undefined) { - this.shouldAllowRequest = true; - } - return this.shouldAllowRequest - ? Ci.nsIContentAnalysisResponse.eAllow - : Ci.nsIContentAnalysisResponse.eBlock; - }, - - // nsIContentAnalysis methods - async analyzeContentRequest(request, _autoAcknowledge) { - info( - "Mock ContentAnalysis service: analyzeContentRequest, this.shouldAllowRequest=" + - this.shouldAllowRequest + - ", this.errorValue=" + - this.errorValue - ); - this.calls.push(request); - if (this.errorValue) { - throw this.errorValue; - } - // Use setTimeout to simulate an async activity - await new Promise(res => setTimeout(res, 0)); - return makeContentAnalysisResponse(this.getAction(), request.requestToken); - }, - - analyzeContentRequestCallback(request, autoAcknowledge, callback) { - info( - "Mock ContentAnalysis service: analyzeContentRequestCallback, this.shouldAllowRequest=" + - this.shouldAllowRequest + - ", this.errorValue=" + - this.errorValue - ); - this.calls.push(request); - if (this.errorValue) { - throw this.errorValue; - } - let response = makeContentAnalysisResponse( - this.getAction(), - request.requestToken - ); - // Use setTimeout to simulate an async activity - setTimeout(() => { - callback.contentResult(response); - }, 0); - }, -}; - -add_setup(async function test_setup() { - mockCA = mockContentAnalysisService(mockCA); -}); - -const TEST_PAGE_URL = - "https://example.com/browser/toolkit/components/printing/tests/simplifyArticleSample.html"; -const TEST_PAGE_URL_2 = - "https://example.com/browser/toolkit/components/printing/tests/longerArticle.html"; - -function addUniqueSuffix(prefix) { - return `${prefix}-${Services.uuid - .generateUUID() - .toString() - .slice(1, -1)}.pdf`; -} - -async function printToDestination(aBrowser, aDestination) { - let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile); - let fileName = addUniqueSuffix(`printDestinationTest-${aDestination}`); - let filePath = PathUtils.join(tmpDir.path, fileName); - - info(`Printing to ${filePath}`); - - let settings = PSSVC.createNewPrintSettings(); - settings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF; - settings.outputDestination = aDestination; - - settings.headerStrCenter = ""; - settings.headerStrLeft = ""; - settings.headerStrRight = ""; - settings.footerStrCenter = ""; - settings.footerStrLeft = ""; - settings.footerStrRight = ""; - - settings.unwriteableMarginTop = 1; /* Just to ensure settings are respected on both */ - let outStream = null; - if (aDestination == Ci.nsIPrintSettings.kOutputDestinationFile) { - settings.toFileName = PathUtils.join(tmpDir.path, fileName); - } else { - is(aDestination, Ci.nsIPrintSettings.kOutputDestinationStream); - outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance( - Ci.nsIFileOutputStream - ); - let tmpFile = tmpDir.clone(); - tmpFile.append(fileName); - outStream.init(tmpFile, -1, 0o666, 0); - settings.outputStream = outStream; - } - - await aBrowser.browsingContext.print(settings); - - return filePath; -} - -function assertContentAnalysisRequest(request, expectedUrl) { - is(request.url.spec, expectedUrl ?? TEST_PAGE_URL, "request has correct URL"); - is( - request.analysisType, - Ci.nsIContentAnalysisRequest.ePrint, - "request has print analysisType" - ); - is( - request.operationTypeForDisplay, - Ci.nsIContentAnalysisRequest.eOperationPrint, - "request has print operationTypeForDisplay" - ); - is(request.textContent, "", "request textContent should be empty"); - is(request.filePath, "", "request filePath should be empty"); - isnot(request.printDataHandle, 0, "request printDataHandle should not be 0"); - isnot(request.printDataSize, 0, "request printDataSize should not be 0"); - ok(!!request.requestToken.length, "request requestToken should not be empty"); -} - -// Printing to a stream is different than going through the print preview dialog because it -// doesn't make a static clone of the document before the print, which causes the -// Content Analysis code to go through a different code path. This is similar to what -// happens when various preferences are set to skip the print preview dialog, for example -// print.prefer_system_dialog. -add_task( - async function testPrintToStreamWithContentAnalysisActiveAndAllowing() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(true); - - let filePath = await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - - await waitForFileToAlmostMatchSize( - filePath, - mockCA.calls[0].printDataSize - ); - - await IOUtils.remove(filePath); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task( - async function testPrintToStreamAfterNavigationWithContentAnalysisActiveAndAllowing() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(true); - - let filePath = await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - mockCA.clearCalls(); - - await IOUtils.remove(filePath); - - BrowserTestUtils.startLoadingURIString( - helper.sourceBrowser, - TEST_PAGE_URL_2 - ); - await BrowserTestUtils.browserLoaded(helper.sourceBrowser); - - filePath = await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0], TEST_PAGE_URL_2); - await waitForFileToAlmostMatchSize( - filePath, - mockCA.calls[0].printDataSize - ); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task( - async function testPrintToStreamWithContentAnalysisActiveAndBlocking() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(false); - - try { - await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - ok(false, "Content analysis should make this fail to print"); - } catch (e) { - ok( - /NS_ERROR_CONTENT_BLOCKED/.test(e.toString()), - "Got content blocked error" - ); - } - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task(async function testPrintToStreamWithContentAnalysisReturningError() { - await PrintHelper.withTestPage( - async helper => { - expectUncaughtException(); - mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE); - - try { - await printToDestination( - helper.sourceBrowser, - Ci.nsIPrintSettings.kOutputDestinationFile - ); - ok(false, "Content analysis should make this fail to print"); - } catch (e) { - ok( - /NS_ERROR_NOT_AVAILABLE/.test(e.toString()), - "Error in mock CA was propagated out" - ); - } - is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis"); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); -}); - -add_task(async function testPrintThroughDialogWithContentAnalysisActive() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(true); - - await helper.startPrint(); - let fileName = addUniqueSuffix(`printDialogTest`); - let file = helper.mockFilePicker(fileName); - info(`Printing to ${file.path}`); - await helper.assertPrintToFile(file, () => { - EventUtils.sendKey("return", helper.win); - }); - - is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis"); - assertContentAnalysisRequest(mockCA.calls[0]); - - await waitForFileToAlmostMatchSize( - file.path, - mockCA.calls[0].printDataSize - ); - }, - TEST_PAGE_URL, - true - ); -}); - -add_task( - async function testPrintThroughDialogWithContentAnalysisActiveAndBlocking() { - await PrintHelper.withTestPage( - async helper => { - mockCA.setupForTest(false); - - await helper.startPrint(); - let fileName = addUniqueSuffix(`printDialogTest`); - let file = helper.mockFilePicker(fileName); - info(`Printing to ${file.path}`); - try { - await helper.assertPrintToFile(file, () => { - EventUtils.sendKey("return", helper.win); - }); - } catch (e) { - ok( - /Wait for target file to get created/.test(e.toString()), - "Target file should not get created" - ); - } - ok(!file.exists(), "File should not exist"); - - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); - } -); - -add_task( - async function testPrintThroughDialogWithContentAnalysisReturningError() { - await PrintHelper.withTestPage( - async helper => { - expectUncaughtException(); - mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE); - - await helper.startPrint(); - let fileName = addUniqueSuffix(`printDialogTest`); - let file = helper.mockFilePicker(fileName); - info(`Printing to ${file.path}`); - try { - await helper.assertPrintToFile(file, () => { - EventUtils.sendKey("return", helper.win); - }); - } catch (e) { - ok( - /Wait for target file to get created/.test(e.toString()), - "Target file should not get created" - ); - } - ok(!file.exists(), "File should not exist"); - - is( - mockCA.calls.length, - 1, - "Correct number of calls to Content Analysis" - ); - assertContentAnalysisRequest(mockCA.calls[0]); - }, - TEST_PAGE_URL, - true - ); - } -); diff --git a/toolkit/components/contentanalysis/tests/browser/changing_page_for_print.html b/toolkit/components/contentanalysis/tests/browser/changing_page_for_print.html deleted file mode 100644 index de6f9001aa82..000000000000 --- a/toolkit/components/contentanalysis/tests/browser/changing_page_for_print.html +++ /dev/null @@ -1,12 +0,0 @@ - -

Some random text

- -

-
diff --git a/toolkit/components/contentanalysis/tests/browser/head.js b/toolkit/components/contentanalysis/tests/browser/head.js
deleted file mode 100644
index e645caa2d71f..000000000000
--- a/toolkit/components/contentanalysis/tests/browser/head.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { MockRegistrar } = ChromeUtils.importESModule(
-  "resource://testing-common/MockRegistrar.sys.mjs"
-);
-
-// Wraps the given object in an XPConnect wrapper and, if an interface
-// is passed, queries the result to that interface.
-function xpcWrap(obj, iface) {
-  let ifacePointer = Cc[
-    "@mozilla.org/supports-interface-pointer;1"
-  ].createInstance(Ci.nsISupportsInterfacePointer);
-
-  ifacePointer.data = obj;
-  if (iface) {
-    return ifacePointer.data.QueryInterface(iface);
-  }
-  return ifacePointer.data;
-}
-
-/**
- * Mock a (set of) service(s) as the object mockService.
- *
- * @param {[string]} serviceNames
- *                   array of services names that mockService will be
- *                   allowed to QI to.  Must include the name of the
- *                   service referenced by contractId.
- * @param {string}   contractId
- *                   the component ID that will reference the mock object
- *                   instead of the original service
- * @param {object}   interfaceObj
- *                   interface object for the component
- * @param {object}   mockService
- *                   object that satisfies the contract well
- *                   enough to use as a mock of it
- * @returns {object} The newly-mocked service
- */
-function mockService(serviceNames, contractId, interfaceObj, mockService) {
-  // xpcWrap allows us to mock [implicit_jscontext] methods.
-  let newService = {
-    ...mockService,
-    QueryInterface: ChromeUtils.generateQI(serviceNames),
-  };
-  let o = xpcWrap(newService, interfaceObj);
-  let cid = MockRegistrar.register(contractId, o);
-  registerCleanupFunction(() => {
-    MockRegistrar.unregister(cid);
-  });
-  return newService;
-}
-
-/**
- * Mock the nsIContentAnalysis service with the object mockCAService.
- *
- * @param {object}    mockCAService
- *                    the service to mock for nsIContentAnalysis
- * @returns {object}  The newly-mocked service
- */
-function mockContentAnalysisService(mockCAService) {
-  return mockService(
-    ["nsIContentAnalysis"],
-    "@mozilla.org/contentanalysis;1",
-    Ci.nsIContentAnalysis,
-    mockCAService
-  );
-}
-
-/**
- * Make an nsIContentAnalysisResponse.
- *
- * @param {number} action The action to take, from the
- *  nsIContentAnalysisResponse.Action enum.
- * @param {string} token The requestToken.
- * @returns {object} An object that conforms to nsIContentAnalysisResponse.
- */
-function makeContentAnalysisResponse(action, token) {
-  return {
-    action,
-    shouldAllowContent: action != Ci.nsIContentAnalysisResponse.eBlock,
-    requestToken: token,
-    acknowledge: _acknowledgement => {},
-  };
-}
-
-async function waitForFileToAlmostMatchSize(filePath, expectedSize) {
-  // In Cocoa the CGContext adds a hash, plus there are other minor
-  // non-user-visible differences, so we need to be a bit more sloppy there.
-  //
-  // We see one byte difference in Windows and Linux on automation sometimes,
-  // though files are consistently the same locally, that needs
-  // investigation, but it's probably harmless.
-  // Note that this is copied from browser_print_stream.js.
-  const maxSizeDifference = AppConstants.platform == "macosx" ? 100 : 3;
-
-  // Buffering shenanigans? Wait for sizes to match... There's no great
-  // IOUtils methods to force a flush without writing anything...
-  // Note that this means if this results in a timeout this is exactly
-  // the same as a test failure.
-  // This is taken from toolkit/components/printing/tests/browser_print_stream.js
-  await TestUtils.waitForCondition(async function () {
-    let fileStat = await IOUtils.stat(filePath);
-
-    info("got size: " + fileStat.size + " expected: " + expectedSize);
-    Assert.greater(
-      fileStat.size,
-      0,
-      "File should not be empty: " + fileStat.size
-    );
-    return Math.abs(fileStat.size - expectedSize) <= maxSizeDifference;
-  }, "Sizes should (almost) match");
-}
diff --git a/toolkit/components/printing/tests/head.js b/toolkit/components/printing/tests/head.js
index e2a83463a65e..8e8c2d1754c9 100644
--- a/toolkit/components/printing/tests/head.js
+++ b/toolkit/components/printing/tests/head.js
@@ -60,9 +60,6 @@ class PrintHelper {
   }
 
   static getTestPageUrl(pathName) {
-    if (pathName.startsWith("http://")) {
-      return pathName;
-    }
     const testPath = getRootDirectory(gTestPath).replace(
       "chrome://mochitests/content",
       "http://example.com"
@@ -71,9 +68,6 @@ class PrintHelper {
   }
 
   static getTestPageUrlHTTPS(pathName) {
-    if (pathName.startsWith("https://")) {
-      return pathName;
-    }
     const testPath = getRootDirectory(gTestPath).replace(
       "chrome://mochitests/content",
       "https://example.com"
diff --git a/toolkit/locales/en-US/toolkit/contentanalysis/contentanalysis.ftl b/toolkit/locales/en-US/toolkit/contentanalysis/contentanalysis.ftl
index 41c18a48e37e..932507e5ad46 100644
--- a/toolkit/locales/en-US/toolkit/contentanalysis/contentanalysis.ftl
+++ b/toolkit/locales/en-US/toolkit/contentanalysis/contentanalysis.ftl
@@ -20,12 +20,8 @@ contentanalysis-slow-agent-dialog-body-clipboard = { $agent } is reviewing what
 # Variables:
 #   $agent - The name of the DLP agent doing the analysis
 contentanalysis-slow-agent-dialog-body-dropped-text = { $agent } is reviewing the text you dropped against your organization’s data policies. This may take a moment.
-# Variables:
-#   $agent - The name of the DLP agent doing the analysis
-contentanalysis-slow-agent-dialog-body-print = { $agent } is reviewing what you printed against your organization’s data policies. This may take a moment.
 contentanalysis-operationtype-clipboard = clipboard
 contentanalysis-operationtype-dropped-text = dropped text
-contentanalysis-operationtype-print = print
 #   $filename - The filename associated with the request, such as "aFile.txt"
 contentanalysis-customdisplaystring-description = upload of “{ $filename }”
 
diff --git a/widget/nsIPrintSettings.idl b/widget/nsIPrintSettings.idl
index daf0e145f429..2355e776e012 100644
--- a/widget/nsIPrintSettings.idl
+++ b/widget/nsIPrintSettings.idl
@@ -335,7 +335,7 @@ interface nsIPrintSettings : nsISupports
    */
   attribute AString toFileName;
 
-  attribute nsIOutputStream outputStream; /* for kOutputDestinationStream */
+  attribute nsIOutputStream outputStream; /* for kOutputDestinationPrinter */
 
   [infallible] attribute long printPageDelay; /* in milliseconds */
 
diff --git a/widget/windows/nsFilePicker.cpp b/widget/windows/nsFilePicker.cpp
index 2a4593798808..c9c7ae20f3ff 100644
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -735,11 +735,7 @@ nsFilePicker::CheckContentAnalysisService() {
     auto contentAnalysisCallback =
         mozilla::MakeRefPtr(
             [promise](nsIContentAnalysisResponse* aResponse) {
-              bool shouldAllow = false;
-              mozilla::DebugOnly rv =
-                  aResponse->GetShouldAllowContent(&shouldAllow);
-              MOZ_ASSERT(NS_SUCCEEDED(rv));
-              promise->Resolve(shouldAllow, __func__);
+              promise->Resolve(aResponse->GetShouldAllowContent(), __func__);
             },
             [promise](nsresult aError) { promise->Reject(aError, __func__); });