Backed out changeset 74fc90e1d05d (
bug 1279699) for causing various crash regressions.
--- a/gfx/2d/DrawEventRecorder.cpp
+++ b/gfx/2d/DrawEventRecorder.cpp
@@ -31,18 +31,17 @@ DrawEventRecorderPrivate::RecordEvent(co
WriteElement(*mOutputStream, aEvent.mType);
aEvent.RecordToStream(*mOutputStream);
Flush();
}
DrawEventRecorderFile::DrawEventRecorderFile(const char *aFilename)
- : DrawEventRecorderPrivate(nullptr)
- , mOutputFilename(aFilename)
+ : DrawEventRecorderPrivate(nullptr)
, mOutputFile(aFilename, ofstream::binary)
{
mOutputStream = &mOutputFile;
WriteHeader();
}
DrawEventRecorderFile::~DrawEventRecorderFile()
@@ -51,35 +50,16 @@ DrawEventRecorderFile::~DrawEventRecorde
}
void
DrawEventRecorderFile::Flush()
{
mOutputFile.flush();
}
-void
-DrawEventRecorderFile::OpenAndTruncate()
-{
- if (mOutputFile.is_open()) {
- return;
- }
-
- mOutputFile.open(mOutputFilename.c_str(), ofstream::binary | ofstream::trunc);
- WriteHeader();
-}
-
-void
-DrawEventRecorderFile::Close()
-{
- MOZ_ASSERT(mOutputFile.is_open());
-
- mOutputFile.close();
-}
-
DrawEventRecorderMemory::DrawEventRecorderMemory()
: DrawEventRecorderPrivate(nullptr)
{
mOutputStream = &mMemoryStream;
WriteHeader();
}
--- a/gfx/2d/DrawEventRecorder.h
+++ b/gfx/2d/DrawEventRecorder.h
@@ -5,17 +5,16 @@
#ifndef MOZILLA_GFX_DRAWEVENTRECORDER_H_
#define MOZILLA_GFX_DRAWEVENTRECORDER_H_
#include "2D.h"
#include "RecordedEvent.h"
#include <ostream>
#include <fstream>
-#include <string>
#if defined(_MSC_VER)
#include <unordered_set>
#else
#include <set>
#endif
namespace mozilla {
@@ -74,34 +73,19 @@ protected:
class DrawEventRecorderFile : public DrawEventRecorderPrivate
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile)
explicit DrawEventRecorderFile(const char *aFilename);
~DrawEventRecorderFile();
- /**
- * Re-opens and truncates the file. The recorder does NOT forget which objects
- * it has recorded. This can be used with Close, so that a recording can be
- * processed in chunks. If the file is already open this does nothing.
- */
- void OpenAndTruncate();
-
- /**
- * Closes the file so that it can be processed. The recorder does NOT forget
- * which objects it has recorded. This can be used with OpenAndTruncate, so
- * that a recording can be processed in chunks. The file must be open.
- */
- void Close();
-
private:
virtual void Flush();
- std::string mOutputFilename;
std::ofstream mOutputFile;
};
class DrawEventRecorderMemory final : public DrawEventRecorderPrivate
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderMemory)
--- a/layout/printing/ipc/PRemotePrintJob.ipdl
+++ b/layout/printing/ipc/PRemotePrintJob.ipdl
@@ -19,17 +19,18 @@ both:
parent:
// Initialize the real print device with the given information.
async InitializePrint(nsString aDocumentTitle, nsString aPrintToFile,
int32_t aStartPage, int32_t aEndPage);
// Translate the stored page recording and play back the events to the real
// print device.
- async ProcessPage(nsCString aPageFileName);
+ // This will always deallocate the shared memory.
+ async ProcessPage(Shmem aStoredPage);
// This informs the real print device that we've finished, so it can trigger
// the actual print.
async FinalizePrint();
// Report a state change to listeners in the parent process.
async StateChange(long aStateFlags,
nsresult aStatus);
--- a/layout/printing/ipc/RemotePrintJobChild.cpp
+++ b/layout/printing/ipc/RemotePrintJobChild.cpp
@@ -42,22 +42,22 @@ bool
RemotePrintJobChild::RecvPrintInitializationResult(const nsresult& aRv)
{
mPrintInitialized = true;
mInitializationResult = aRv;
return true;
}
void
-RemotePrintJobChild::ProcessPage(const nsCString& aPageFileName)
+RemotePrintJobChild::ProcessPage(Shmem& aStoredPage)
{
MOZ_ASSERT(mPagePrintTimer);
mPagePrintTimer->WaitForRemotePrint();
- Unused << SendProcessPage(aPageFileName);
+ Unused << SendProcessPage(aStoredPage);
}
bool
RemotePrintJobChild::RecvPageProcessed()
{
MOZ_ASSERT(mPagePrintTimer);
mPagePrintTimer->RemotePrintFinished();
--- a/layout/printing/ipc/RemotePrintJobChild.h
+++ b/layout/printing/ipc/RemotePrintJobChild.h
@@ -31,17 +31,17 @@ public:
nsresult InitializePrint(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage);
bool RecvPrintInitializationResult(const nsresult& aRv) final;
- void ProcessPage(const nsCString& aPageFileName);
+ void ProcessPage(Shmem& aStoredPage);
bool RecvPageProcessed() final;
bool RecvAbortPrint(const nsresult& aRv) final;
void SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer);
void SetPrintEngine(nsPrintEngine* aPrintEngine);
--- a/layout/printing/ipc/RemotePrintJobParent.cpp
+++ b/layout/printing/ipc/RemotePrintJobParent.cpp
@@ -1,24 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemotePrintJobParent.h"
-#include <fstream>
+#include <istream>
#include "gfxContext.h"
#include "mozilla/Attributes.h"
#include "mozilla/Unused.h"
-#include "nsAppDirectoryServiceDefs.h"
#include "nsComponentManagerUtils.h"
-#include "nsDirectoryServiceUtils.h"
#include "nsDeviceContext.h"
#include "nsIDeviceContextSpec.h"
#include "nsIPrintSettings.h"
#include "nsIWebProgressListener.h"
#include "PrintTranslator.h"
namespace mozilla {
namespace layout {
@@ -78,73 +76,56 @@ RemotePrintJobParent::InitializePrintDev
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
bool
-RemotePrintJobParent::RecvProcessPage(const nsCString& aPageFileName)
+RemotePrintJobParent::RecvProcessPage(Shmem&& aStoredPage)
{
- nsresult rv = PrintPage(aPageFileName);
+ nsresult rv = PrintPage(aStoredPage);
+
+ // Always deallocate the shared memory no matter what the result.
+ if (!DeallocShmem(aStoredPage)) {
+ NS_WARNING("Failed to deallocated shared memory, remote print will abort.");
+ rv = NS_ERROR_FAILURE;
+ }
if (NS_FAILED(rv)) {
Unused << SendAbortPrint(rv);
} else {
Unused << SendPageProcessed();
}
return true;
}
nsresult
-RemotePrintJobParent::PrintPage(const nsCString& aPageFileName)
+RemotePrintJobParent::PrintPage(const Shmem& aStoredPage)
{
MOZ_ASSERT(mPrintDeviceContext);
nsresult rv = mPrintDeviceContext->BeginPage();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- nsCOMPtr<nsIFile> recordingFile;
- rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
- getter_AddRefs(recordingFile));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- rv = recordingFile->AppendNative(aPageFileName);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsAutoCString recordingPath;
- rv = recordingFile->GetNativePath(recordingPath);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- std::ifstream recording(recordingPath.get(), std::ifstream::binary);
+ std::istringstream recording(std::string(aStoredPage.get<char>(),
+ aStoredPage.Size<char>()));
if (!mPrintTranslator->TranslateRecording(recording)) {
return NS_ERROR_FAILURE;
}
rv = mPrintDeviceContext->EndPage();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- recording.close();
- rv = recordingFile->Remove(/* recursive= */ false);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
return NS_OK;
}
bool
RemotePrintJobParent::RecvFinalizePrint()
{
// EndDocument is sometimes called in the child even when BeginDocument has
// not been called. See bug 1223332.
--- a/layout/printing/ipc/RemotePrintJobParent.h
+++ b/layout/printing/ipc/RemotePrintJobParent.h
@@ -29,17 +29,17 @@ public:
void ActorDestroy(ActorDestroyReason aWhy) final;
bool RecvInitializePrint(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage) final;
- bool RecvProcessPage(const nsCString& aPageFileName) final;
+ bool RecvProcessPage(Shmem&& aStoredPage) final;
bool RecvFinalizePrint() final;
bool RecvAbortPrint(const nsresult& aRv) final;
bool RecvStateChange(const long& aStateFlags,
const nsresult& aStatus) final;
@@ -65,17 +65,17 @@ public:
private:
~RemotePrintJobParent() final;
nsresult InitializePrintDevice(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage);
- nsresult PrintPage(const nsCString& aPageFileName);
+ nsresult PrintPage(const Shmem& aStoredPage);
nsCOMPtr<nsIPrintSettings> mPrintSettings;
RefPtr<nsDeviceContext> mPrintDeviceContext;
UniquePtr<PrintTranslator> mPrintTranslator;
nsCOMArray<nsIWebProgressListener> mPrintProgressListeners;
};
} // namespace layout
--- a/widget/nsDeviceContextSpecProxy.cpp
+++ b/widget/nsDeviceContextSpecProxy.cpp
@@ -9,21 +9,18 @@
#include "gfxASurface.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/DrawEventRecorder.h"
#include "mozilla/gfx/PrintTargetThebes.h"
#include "mozilla/layout/RemotePrintJobChild.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Unused.h"
#include "nsComponentManagerUtils.h"
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsDirectoryServiceUtils.h"
#include "nsIPrintSession.h"
#include "nsIPrintSettings.h"
-#include "nsIUUIDGenerator.h"
using mozilla::Unused;
using namespace mozilla;
using namespace mozilla::gfx;
NS_IMPL_ISUPPORTS(nsDeviceContextSpecProxy, nsIDeviceContextSpec)
@@ -132,47 +129,17 @@ nsDeviceContextSpecProxy::GetPrintingSca
return mRealDeviceContextSpec->GetPrintingScale();
}
NS_IMETHODIMP
nsDeviceContextSpecProxy::BeginDocument(const nsAString& aTitle,
const nsAString& aPrintToFileName,
int32_t aStartPage, int32_t aEndPage)
{
- nsCOMPtr<nsIFile> recordingFile;
- nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
- getter_AddRefs(recordingFile));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsCOMPtr<nsIUUIDGenerator> uuidgen =
- do_GetService("@mozilla.org/uuid-generator;1", &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsID uuid;
- rv = uuidgen->GenerateUUIDInPlace(&uuid);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- char uuidChars[NSID_LENGTH];
- uuid.ToProvidedString(uuidChars);
- mRecorderFile.AssignASCII(uuidChars);
- rv = recordingFile->AppendNative(mRecorderFile);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsAutoCString recordingPath;
- rv = recordingFile->GetNativePath(recordingPath);
-
- mRecorder = new mozilla::gfx::DrawEventRecorderFile(recordingPath.get());
+ mRecorder = new mozilla::gfx::DrawEventRecorderMemory();
return mRemotePrintJob->InitializePrint(nsString(aTitle),
nsString(aPrintToFileName),
aStartPage, aEndPage);
}
NS_IMETHODIMP
nsDeviceContextSpecProxy::EndDocument()
{
@@ -185,23 +152,39 @@ nsDeviceContextSpecProxy::AbortDocument(
{
Unused << mRemotePrintJob->SendAbortPrint(NS_OK);
return NS_OK;
}
NS_IMETHODIMP
nsDeviceContextSpecProxy::BeginPage()
{
- // Reopen the file, if necessary, ready for the next page.
- mRecorder->OpenAndTruncate();
-
return NS_OK;
}
NS_IMETHODIMP
nsDeviceContextSpecProxy::EndPage()
{
+ // Save the current page recording to shared memory.
+ mozilla::ipc::Shmem storedPage;
+ size_t recordingSize = mRecorder->RecordingSize();
+ if (!mRemotePrintJob->AllocShmem(recordingSize,
+ mozilla::ipc::SharedMemory::TYPE_BASIC,
+ &storedPage)) {
+ NS_WARNING("Failed to create shared memory for remote printing.");
+ return NS_ERROR_FAILURE;
+ }
+
+ bool success = mRecorder->CopyRecording(storedPage.get<char>(), recordingSize);
+ if (!success) {
+ NS_WARNING("Copying recording to shared memory was not succesful.");
+ return NS_ERROR_FAILURE;
+ }
+
+ // Wipe the recording to free memory. The recorder does not forget which data
+ // backed objects that it has stored.
+ mRecorder->WipeRecording();
+
// Send the page recording to the parent.
- mRecorder->Close();
- mRemotePrintJob->ProcessPage(mRecorderFile);
+ mRemotePrintJob->ProcessPage(storedPage);
return NS_OK;
}
--- a/widget/nsDeviceContextSpecProxy.h
+++ b/widget/nsDeviceContextSpecProxy.h
@@ -4,23 +4,22 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsDeviceContextSpecProxy_h
#define nsDeviceContextSpecProxy_h
#include "nsIDeviceContextSpec.h"
#include "nsCOMPtr.h"
-#include "nsString.h"
class nsIPrintSession;
namespace mozilla {
namespace gfx {
-class DrawEventRecorderFile;
+class DrawEventRecorderMemory;
}
namespace layout {
class RemotePrintJobChild;
}
}
class nsDeviceContextSpecProxy final : public nsIDeviceContextSpec
@@ -53,13 +52,12 @@ public:
private:
~nsDeviceContextSpecProxy() {}
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsIPrintSession> mPrintSession;
nsCOMPtr<nsIDeviceContextSpec> mRealDeviceContextSpec;
RefPtr<mozilla::layout::RemotePrintJobChild> mRemotePrintJob;
- RefPtr<mozilla::gfx::DrawEventRecorderFile> mRecorder;
- nsCString mRecorderFile;
+ RefPtr<mozilla::gfx::DrawEventRecorderMemory> mRecorder;
};
#endif // nsDeviceContextSpecProxy_h
--- a/xpcom/io/nsAppDirectoryServiceDefs.h
+++ b/xpcom/io/nsAppDirectoryServiceDefs.h
@@ -105,14 +105,11 @@
//
// New code should avoid writing to the filesystem from the content process
// and should instead proxy through the parent process whenever possible.
//
// At present, all sandboxed content processes use the same directory for
// NS_APP_CONTENT_PROCESS_TEMP_DIR, but that should not be relied upon.
//
#define NS_APP_CONTENT_PROCESS_TEMP_DIR "ContentTmpD"
-#else
-// Otherwise NS_APP_CONTENT_PROCESS_TEMP_DIR must match NS_OS_TEMP_DIR.
-#define NS_APP_CONTENT_PROCESS_TEMP_DIR "TmpD"
#endif // (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
#endif // nsAppDirectoryServiceDefs_h___