diff --git a/b2g/components/test/mochitest/screenshot_helper.js b/b2g/components/test/mochitest/screenshot_helper.js index d10234f9281..cf40528f0ee 100644 --- a/b2g/components/test/mochitest/screenshot_helper.js +++ b/b2g/components/test/mochitest/screenshot_helper.js @@ -1,6 +1,8 @@ const Cu = Components.utils; const Ci = Components.interfaces; +Cu.importGlobalProperties(['File']); + const { Services } = Cu.import("resource://gre/modules/Services.jsm"); // Load a duplicated copy of the jsm to prevent messing with the currently running one @@ -25,7 +27,7 @@ function next() { let steps = [ function getScreenshot() { let screenshot = Screenshot.get(); - assert.ok(screenshot instanceof Ci.nsIDOMFile, + assert.ok(screenshot instanceof File, "Screenshot.get() returns a File"); next(); }, diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 55194c01e82..233e1d1aaca 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1210,6 +1210,9 @@ pref("security.sandbox.content.level", 1); pref("security.sandbox.content.level", 0); #endif +// ID (a UUID when set by gecko) that is used as a per profile suffix to a low +// integrity temp directory. +pref("security.sandbox.content.tempDirSuffix", ""); #if defined(MOZ_STACKWALKING) // This controls the depth of stack trace that is logged when Windows sandbox diff --git a/build/gen_mach_buildprops.py b/build/gen_mach_buildprops.py index 04ba2e7044e..7fe5c6cf8ec 100644 --- a/build/gen_mach_buildprops.py +++ b/build/gen_mach_buildprops.py @@ -40,7 +40,7 @@ def getMarProperties(filename, partial=False): '%sMarHash' % martype: mar_hash, } -def getUrlProperties(filename): +def getUrlProperties(filename, package): # let's create a switch case using name-spaces/dict # rather than a long if/else with duplicate code property_conditions = [ @@ -57,9 +57,7 @@ def getUrlProperties(filename): ('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')), ('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))), ('testPackagesUrl', lambda m: m.endswith('test_packages.json')), - # packageUrl must be last! - ('packageUrl', lambda m: (not m.endswith('.json') and - not m.endswith('tests.zip'))), + ('packageUrl', lambda m: m.endswith(package)), ] url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz|json))$''') properties = {} @@ -102,10 +100,13 @@ if __name__ == '__main__': parser.add_argument("--upload-files", required=True, nargs="+", action="store", dest="upload_files", help="List of files to be uploaded.") + parser.add_argument("--package", required=True, + action="store", dest="package", + help="Filename of the build package") args = parser.parse_args() json_data = getMarProperties(args.complete_mar_file) - json_data.update(getUrlProperties(args.upload_output)) + json_data.update(getUrlProperties(args.upload_output, args.package)) if args.partial_mar_file: json_data.update(getMarProperties(args.partial_mar_file, partial=True)) @@ -119,6 +120,7 @@ if __name__ == '__main__': json_data['partialInfo'] = getPartialInfo(json_data) json_data['uploadFiles'] = args.upload_files + json_data['packageFilename'] = args.package with open('mach_build_properties.json', 'w') as outfile: json.dump(json_data, outfile, indent=4) diff --git a/build/moz-automation.mk b/build/moz-automation.mk index 0c37c67bb3a..7a8e037bc4b 100644 --- a/build/moz-automation.mk +++ b/build/moz-automation.mk @@ -99,7 +99,7 @@ automation/l10n-check: automation/pretty-l10n-check automation/update-packaging: automation/pretty-update-packaging automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS)) - $(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) --upload-files $(abspath $(UPLOAD_FILES)) + $(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) --upload-files $(abspath $(UPLOAD_FILES)) --package $(PACKAGE) # We need the log from make upload to grep it for urls in order to set # properties. diff --git a/dom/apps/ImportExport.jsm b/dom/apps/ImportExport.jsm index e990b9a6c53..a2b13f61927 100644 --- a/dom/apps/ImportExport.jsm +++ b/dom/apps/ImportExport.jsm @@ -14,6 +14,8 @@ Cu.import("resource://gre/modules/AppsUtils.jsm"); Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Webapps.jsm"); +Cu.importGlobalProperties(['File']); + XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); @@ -284,7 +286,7 @@ this.ImportExport = { throw "NoBlobFound"; } - let isFileBlob = aBlob instanceof Ci.nsIDOMFile; + let isFileBlob = aBlob instanceof File; // We can't QI the DOMFile to nsIFile, so we need to create one. let zipFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); if (!isFileBlob) { @@ -498,7 +500,7 @@ this.ImportExport = { throw "NoBlobFound"; } - let isFileBlob = aBlob instanceof Ci.nsIDOMFile; + let isFileBlob = aBlob instanceof File; // We can't QI the DOMFile to nsIFile, so we need to create one. let zipFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); if (!isFileBlob) { diff --git a/dom/archivereader/ArchiveRequest.cpp b/dom/archivereader/ArchiveRequest.cpp index 6a857a17a3d..b840a82b2d1 100644 --- a/dom/archivereader/ArchiveRequest.cpp +++ b/dom/archivereader/ArchiveRequest.cpp @@ -177,7 +177,6 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx, nsTArray>& aFileList) { JS::Rooted array(aCx, JS_NewArrayObject(aCx, aFileList.Length())); - nsresult rv; if (!array) { return NS_ERROR_OUT_OF_MEMORY; @@ -188,14 +187,12 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx, nsRefPtr file = aFileList[i]; nsString filename; - rv = file->GetName(filename); - NS_ENSURE_SUCCESS(rv, rv); + file->GetName(filename); str = JS_NewUCStringCopyZ(aCx, filename.get()); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); - if (NS_FAILED(rv) || - !JS_DefineElement(aCx, array, i, str, JSPROP_ENUMERATE)) { + if (!JS_DefineElement(aCx, array, i, str, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } } @@ -217,8 +214,7 @@ ArchiveRequest::GetFileResult(JSContext* aCx, nsRefPtr file = aFileList[i]; nsString filename; - nsresult rv = file->GetName(filename); - NS_ENSURE_SUCCESS(rv, rv); + file->GetName(filename); if (filename == mFilename) { if (!ToJSValue(aCx, file, aValue)) { diff --git a/dom/base/File.cpp b/dom/base/File.cpp index a1df543dbf9..c8e9d94cd95 100644 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -439,22 +439,6 @@ Blob::GetInternalStream(nsIInputStream** aStream) //////////////////////////////////////////////////////////////////////////// // mozilla::dom::File implementation -NS_IMPL_CYCLE_COLLECTION_CLASS(File) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(File, Blob) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(File, Blob) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(File) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile) - NS_INTERFACE_MAP_ENTRY(nsIDOMFile) -NS_INTERFACE_MAP_END_INHERITING(Blob) - -NS_IMPL_ADDREF_INHERITED(File, Blob) -NS_IMPL_RELEASE_INHERITED(File, Blob) - File::File(nsISupports* aParent, BlobImpl* aImpl) : Blob(aParent, aImpl) { @@ -553,17 +537,16 @@ File::WrapObject(JSContext* aCx, JS::Handle aGivenProto) return FileBinding::Wrap(aCx, this, aGivenProto); } -NS_IMETHODIMP +void File::GetName(nsAString& aFileName) { mImpl->GetName(aFileName); - return NS_OK; } -NS_IMETHODIMP -File::GetPath(nsAString& aPath) +void +File::GetPath(nsAString& aPath, ErrorResult& aRv) { - return mImpl->GetPath(aPath); + mImpl->GetPath(aPath, aRv); } Date @@ -583,53 +566,16 @@ File::GetLastModified(ErrorResult& aRv) return mImpl->GetLastModified(aRv); } -NS_IMETHODIMP -File::GetLastModifiedDate(JSContext* aCx, - JS::MutableHandle aDate) -{ - ErrorResult rv; - Date value = GetLastModifiedDate(rv); - if (rv.Failed()) { - return rv.StealNSResult(); - } - - if (!value.ToDateObject(aCx, aDate)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - return NS_OK; -} - -NS_IMETHODIMP -File::GetMozFullPath(nsAString& aFileName) -{ - ErrorResult rv; - GetMozFullPath(aFileName, rv); - return rv.StealNSResult(); -} - void File::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv) { mImpl->GetMozFullPath(aFilename, aRv); } -NS_IMETHODIMP -File::GetMozFullPathInternal(nsAString& aFileName) +void +File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) { - ErrorResult rv; - mImpl->GetMozFullPathInternal(aFileName, rv); - return rv.StealNSResult(); -} - -NS_IMETHODIMP -File::GetMozLastModifiedDate(int64_t* aDate) -{ - MOZ_ASSERT(aDate); - - ErrorResult rv; - *aDate = GetLastModified(rv); - return rv.StealNSResult(); + mImpl->GetMozFullPathInternal(aFileName, aRv); } // Makes sure that aStart and aEnd is less then or equal to aSize and greater @@ -817,12 +763,11 @@ BlobImplBase::GetName(nsAString& aName) aName = mName; } -nsresult -BlobImplBase::GetPath(nsAString& aPath) +void +BlobImplBase::GetPath(nsAString& aPath, ErrorResult& aRv) { NS_ASSERTION(mIsFile, "Should only be called on files"); aPath = mPath; - return NS_OK; } void @@ -1321,9 +1266,9 @@ FileList::GetLength(uint32_t* aLength) } NS_IMETHODIMP -FileList::Item(uint32_t aIndex, nsIDOMFile **aFile) +FileList::Item(uint32_t aIndex, nsISupports** aFile) { - nsRefPtr file = Item(aIndex); + nsCOMPtr file = Item(aIndex); file.forget(aFile); return NS_OK; } diff --git a/dom/base/File.h b/dom/base/File.h index c77620871e2..5c660b11a40 100644 --- a/dom/base/File.h +++ b/dom/base/File.h @@ -20,7 +20,7 @@ #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" #include "nsCOMPtr.h" -#include "nsIDOMFile.h" +#include "nsIDOMBlob.h" #include "nsIDOMFileList.h" #include "nsIFile.h" #include "nsIMutable.h" @@ -157,17 +157,10 @@ private: }; class File final : public Blob - , public nsIDOMFile { friend class Blob; public: - NS_DECL_NSIDOMFILE - NS_FORWARD_NSIDOMBLOB(Blob::) - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(File, Blob); - // Note: BlobImpl must be a File in order to use this method. // Check impl->IsFile(). static File* @@ -245,15 +238,18 @@ public: const ChromeFilePropertyBag& aBag, ErrorResult& aRv); - // XPCOM GetName is OK + void GetName(nsAString& aName); int64_t GetLastModified(ErrorResult& aRv); Date GetLastModifiedDate(ErrorResult& aRv); + void GetPath(nsAString& aName, ErrorResult& aRv); void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv); + void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv); + protected: virtual bool HasFileInterface() const override { return true; } @@ -276,7 +272,7 @@ public: virtual void GetName(nsAString& aName) = 0; - virtual nsresult GetPath(nsAString& aName) = 0; + virtual void GetPath(nsAString& aName, ErrorResult& aRv) = 0; virtual int64_t GetLastModified(ErrorResult& aRv) = 0; @@ -404,7 +400,7 @@ public: virtual void GetName(nsAString& aName) override; - virtual nsresult GetPath(nsAString& aName) override; + virtual void GetPath(nsAString& aName, ErrorResult& aRv) override; virtual int64_t GetLastModified(ErrorResult& aRv) override; diff --git a/dom/base/FileIOObject.h b/dom/base/FileIOObject.h index cb96b93b89c..67069d8971c 100644 --- a/dom/base/FileIOObject.h +++ b/dom/base/FileIOObject.h @@ -9,7 +9,6 @@ #include "mozilla/DOMEventTargetHelper.h" #include "nsIFile.h" -#include "nsIDOMFile.h" #include "nsITimer.h" #include "nsCOMPtr.h" #include "nsIAsyncInputStream.h" diff --git a/dom/base/MultipartBlobImpl.cpp b/dom/base/MultipartBlobImpl.cpp index 3fa6ffa0cce..a98a3659d04 100644 --- a/dom/base/MultipartBlobImpl.cpp +++ b/dom/base/MultipartBlobImpl.cpp @@ -366,8 +366,7 @@ MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow, } // Pre-cache modified date. - int64_t unusedDate; - aRv = blob->GetMozLastModifiedDate(&unusedDate); + blob->GetLastModified(aRv); if (NS_WARN_IF(aRv.Failed())) { return; } diff --git a/dom/base/moz.build b/dom/base/moz.build index 27fcf10ad55..acbaa665e83 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -11,10 +11,10 @@ XPIDL_SOURCES += [ 'nsIContentPolicy.idl', 'nsIContentPolicyBase.idl', 'nsIDocumentEncoder.idl', + 'nsIDOMBlob.idl', 'nsIDOMDataChannel.idl', 'nsIDOMDOMCursor.idl', 'nsIDOMDOMRequest.idl', - 'nsIDOMFile.idl', 'nsIDOMFileList.idl', 'nsIDOMFileReader.idl', 'nsIDOMFormData.idl', diff --git a/dom/base/nsContentPermissionHelper.cpp b/dom/base/nsContentPermissionHelper.cpp index eb6a18acd30..0abb0e9ebdb 100644 --- a/dom/base/nsContentPermissionHelper.cpp +++ b/dom/base/nsContentPermissionHelper.cpp @@ -14,6 +14,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/Event.h" #include "mozilla/dom/PContentPermission.h" #include "mozilla/dom/PermissionMessageUtils.h" #include "mozilla/dom/PContentPermissionRequestParent.h" diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index c29abfe7056..2d026e72478 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -58,6 +58,7 @@ #include "nsIContentViewer.h" #include "mozilla/StyleAnimationValue.h" #include "mozilla/dom/File.h" +#include "mozilla/dom/FileBinding.h" #include "mozilla/dom/DOMRect.h" #include @@ -2592,7 +2593,7 @@ nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult) NS_IMETHODIMP nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile, - nsIDOMFile **aDOMFile) + nsISupports **aDOMFile) { MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); @@ -2608,8 +2609,8 @@ nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile, return NS_ERROR_FAILURE; } - nsRefPtr file = File::CreateFromFile(innerWindow, aFile); - file.forget(aDOMFile); + nsCOMPtr blob = File::CreateFromFile(innerWindow, aFile); + blob.forget(aDOMFile); return NS_OK; } @@ -2858,15 +2859,13 @@ nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx, JSObject* obj = aFile.toObjectOrNull(); - nsISupports* nativeObj = - nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj); - - nsCOMPtr file = do_QueryInterface(nativeObj); - if (file) { + File* file = nullptr; + if (NS_SUCCEEDED(UNWRAP_OBJECT(File, obj, file))) { nsString filePath; - nsresult rv = file->GetMozFullPathInternal(filePath); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; + ErrorResult rv; + file->GetMozFullPathInternal(filePath, rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); } _retval = filePath; diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index d9b2a3cf049..114a9b176a7 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -23,7 +23,6 @@ #include "nsIContentViewer.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" -#include "nsIDOMFile.h" #include "nsPIDOMWindow.h" #include "nsIWebNavigation.h" #include "nsIWebProgress.h" diff --git a/dom/base/nsIDOMFile.idl b/dom/base/nsIDOMBlob.idl similarity index 73% rename from dom/base/nsIDOMFile.idl rename to dom/base/nsIDOMBlob.idl index cc8507aa409..efdc1be84f3 100644 --- a/dom/base/nsIDOMFile.idl +++ b/dom/base/nsIDOMBlob.idl @@ -53,25 +53,3 @@ interface nsIDOMBlob : nsISupports // Return true if this blob is a memory file. [notxpcom] bool isMemoryFile(); }; - -// We want to avoid multiple inheritance of nsIDOMBlob so we can downcast from -// nsIDOMBlob to Blob safely. Our chain is: -// - Blob -> nsIDOMBlob -// - File -> nsIDOMFile and Blob -[scriptable, builtinclass, uuid(cc28cf12-f1d4-44ff-843f-9289aa14613b)] -interface nsIDOMFile : nsISupports -{ - readonly attribute DOMString name; - - readonly attribute DOMString path; - - [implicit_jscontext] - readonly attribute jsval lastModifiedDate; - - readonly attribute DOMString mozFullPath; - - // This performs no security checks! - [noscript] readonly attribute DOMString mozFullPathInternal; - - [noscript] readonly attribute int64_t mozLastModifiedDate; -}; diff --git a/dom/base/nsIDOMFileList.idl b/dom/base/nsIDOMFileList.idl index 29186604c5f..338bd72793e 100644 --- a/dom/base/nsIDOMFileList.idl +++ b/dom/base/nsIDOMFileList.idl @@ -5,11 +5,10 @@ #include "nsISupports.idl" -interface nsIDOMFile; - -[uuid(283aa7b2-da81-4c72-aea2-9797b440fe34)] +[uuid(57128a85-34de-42db-a252-84dd57724a59)] interface nsIDOMFileList : nsISupports { readonly attribute unsigned long length; - nsIDOMFile item(in unsigned long index); + // returns a DOM File object + nsISupports item(in unsigned long index); }; diff --git a/dom/base/nsInProcessTabChildGlobal.cpp b/dom/base/nsInProcessTabChildGlobal.cpp index 53d9f7c2199..6a9502445c8 100644 --- a/dom/base/nsInProcessTabChildGlobal.cpp +++ b/dom/base/nsInProcessTabChildGlobal.cpp @@ -26,6 +26,7 @@ using mozilla::dom::StructuredCloneData; using mozilla::dom::StructuredCloneClosure; using namespace mozilla; +using namespace mozilla::dom; bool nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx, diff --git a/dom/base/nsPropertyTable.cpp b/dom/base/nsPropertyTable.cpp index 58531c6a897..c28ad20a1e5 100644 --- a/dom/base/nsPropertyTable.cpp +++ b/dom/base/nsPropertyTable.cpp @@ -229,7 +229,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, // value is destroyed nsresult result = NS_OK; PropertyListMapEntry *entry = static_cast - (PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject, fallible)); + (PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject, mozilla::fallible)); if (!entry) return NS_ERROR_OUT_OF_MEMORY; // A nullptr entry->key is the sign that the entry has just been allocated diff --git a/dom/base/nsQueryContentEventResult.h b/dom/base/nsQueryContentEventResult.h index 95d0d173af8..f502456c267 100644 --- a/dom/base/nsQueryContentEventResult.h +++ b/dom/base/nsQueryContentEventResult.h @@ -10,6 +10,7 @@ #include "nsIQueryContentEventResult.h" #include "nsString.h" #include "nsRect.h" +#include "Units.h" #include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" diff --git a/dom/bindings/ToJSValue.h b/dom/bindings/ToJSValue.h index 5cfef1895ce..f80652e2c58 100644 --- a/dom/bindings/ToJSValue.h +++ b/dom/bindings/ToJSValue.h @@ -172,7 +172,7 @@ ToJSValue(JSContext* aCx, } // Accept objects that inherit from nsISupports but not nsWrapperCache (e.g. -// nsIDOMFile). +// DOM File). template MOZ_WARN_UNUSED_RESULT typename EnableIf::value && diff --git a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp index 4a06324881a..ac325f088e9 100644 --- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp +++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp @@ -72,14 +72,14 @@ BEGIN_BLUETOOTH_NAMESPACE class BluetoothOppManager::SendFileBatch final { public: - SendFileBatch(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob) + SendFileBatch(const nsAString& aDeviceAddress, Blob* aBlob) : mDeviceAddress(aDeviceAddress) { mBlobs.AppendElement(aBlob); } nsString mDeviceAddress; - nsCOMArray mBlobs; + nsTArray> mBlobs; }; NS_IMETHODIMP @@ -420,7 +420,7 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress, bool BluetoothOppManager::SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob) + Blob* aBlob) { MOZ_ASSERT(NS_IsMainThread()); @@ -434,7 +434,7 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress, void BluetoothOppManager::AppendBlobToSend(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob) + Blob* aBlob) { MOZ_ASSERT(NS_IsMainThread()); @@ -794,7 +794,7 @@ BluetoothOppManager::RetrieveSentFileName() { mFileName.Truncate(); - nsCOMPtr file = do_QueryInterface(mBlob); + nsRefPtr file = static_cast(mBlob.get())->ToFile(); if (file) { file->GetName(mFileName); } diff --git a/dom/bluetooth/bluedroid/BluetoothOppManager.h b/dom/bluetooth/bluedroid/BluetoothOppManager.h index d87bb0aef08..5833846e4a7 100644 --- a/dom/bluetooth/bluedroid/BluetoothOppManager.h +++ b/dom/bluetooth/bluedroid/BluetoothOppManager.h @@ -14,13 +14,13 @@ #include "mozilla/ipc/SocketBase.h" #include "nsCOMArray.h" -class nsIDOMBlob; class nsIOutputStream; class nsIInputStream; class nsIVolumeMountLock; namespace mozilla { namespace dom { +class Blob; class BlobParent; } } @@ -55,7 +55,7 @@ public: bool Listen(); bool SendFile(const nsAString& aDeviceAddress, BlobParent* aActor); - bool SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob); + bool SendFile(const nsAString& aDeviceAddress, Blob* aBlob); bool StopSendingFile(); bool ConfirmReceivingFile(bool aConfirm); @@ -102,7 +102,7 @@ private: void NotifyAboutFileChange(); bool AcquireSdcardMountLock(); void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize); - void AppendBlobToSend(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob); + void AppendBlobToSend(const nsAString& aDeviceAddress, Blob* aBlob); void DiscardBlobsToSend(); bool ProcessNextBatch(); void ConnectInternal(const nsAString& aDeviceAddress); @@ -199,7 +199,7 @@ private: nsAutoArrayPtr mReceivedDataBuffer; int mCurrentBlobIndex; - nsCOMPtr mBlob; + nsRefPtr mBlob; nsTArray mBatches; /** diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index cf7b6118d43..c3f2eb41e3c 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -1827,7 +1827,7 @@ BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress, void BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) { MOZ_ASSERT(NS_IsMainThread()); diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h index 57fe121aba7..bbebf2c96c7 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h @@ -130,7 +130,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable); virtual void @@ -435,7 +435,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable); virtual void diff --git a/dom/bluetooth/bluetooth1/BluetoothService.h b/dom/bluetooth/bluetooth1/BluetoothService.h index 34681517b61..dbb0de23f33 100644 --- a/dom/bluetooth/bluetooth1/BluetoothService.h +++ b/dom/bluetooth/bluetooth1/BluetoothService.h @@ -11,15 +11,13 @@ #include "BluetoothProfileManagerBase.h" #include "nsAutoPtr.h" #include "nsClassHashtable.h" -#include "nsIDOMFile.h" #include "nsIObserver.h" #include "nsTObserverArray.h" #include "nsThreadUtils.h" -class nsIDOMBlob; - namespace mozilla { namespace dom { +class Blob; class BlobChild; class BlobParent; } @@ -241,7 +239,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) = 0; virtual void diff --git a/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.cpp b/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.cpp index 6fd80748951..1fcc1a116ef 100644 --- a/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.cpp +++ b/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.cpp @@ -266,7 +266,7 @@ BluetoothServiceChildProcess::SendFile( void BluetoothServiceChildProcess::SendFile( const nsAString& aDeviceAddress, - nsIDOMBlob* aBlobChild, + Blob* aBlobChild, BluetoothReplyRunnable* aRunnable) { // Parent-process-only method diff --git a/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h b/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h index 712b14f607e..db53344c985 100644 --- a/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h +++ b/dom/bluetooth/bluetooth1/ipc/BluetoothServiceChildProcess.h @@ -111,7 +111,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) override; virtual void diff --git a/dom/bluetooth/bluetooth2/BluetoothService.h b/dom/bluetooth/bluetooth2/BluetoothService.h index 99fcfab7513..d362a79cc35 100644 --- a/dom/bluetooth/bluetooth2/BluetoothService.h +++ b/dom/bluetooth/bluetooth2/BluetoothService.h @@ -12,15 +12,13 @@ #include "BluetoothProfileManagerBase.h" #include "nsAutoPtr.h" #include "nsClassHashtable.h" -#include "nsIDOMFile.h" #include "nsIObserver.h" #include "nsTObserverArray.h" #include "nsThreadUtils.h" -class nsIDOMBlob; - namespace mozilla { namespace dom { +class Blob; class BlobChild; class BlobParent; } @@ -295,7 +293,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) = 0; virtual void diff --git a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp index 867df1aeada..303769395c9 100644 --- a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp +++ b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.cpp @@ -316,7 +316,7 @@ BluetoothServiceChildProcess::SendFile( void BluetoothServiceChildProcess::SendFile( const nsAString& aDeviceAddress, - nsIDOMBlob* aBlobChild, + Blob* aBlobChild, BluetoothReplyRunnable* aRunnable) { // Parent-process-only method diff --git a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h index ab7bdbac5a7..aebf930de77 100644 --- a/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h +++ b/dom/bluetooth/bluetooth2/ipc/BluetoothServiceChildProcess.h @@ -140,7 +140,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) override; virtual void diff --git a/dom/bluetooth/bluez/BluetoothDBusService.cpp b/dom/bluetooth/bluez/BluetoothDBusService.cpp index ab7b86d13fa..a43887267f4 100644 --- a/dom/bluetooth/bluez/BluetoothDBusService.cpp +++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp @@ -4161,7 +4161,7 @@ BluetoothDBusService::SendFile(const nsAString& aDeviceAddress, void BluetoothDBusService::SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) { MOZ_ASSERT(NS_IsMainThread()); diff --git a/dom/bluetooth/bluez/BluetoothDBusService.h b/dom/bluetooth/bluez/BluetoothDBusService.h index b4a9c00136a..c52f3942771 100644 --- a/dom/bluetooth/bluez/BluetoothDBusService.h +++ b/dom/bluetooth/bluez/BluetoothDBusService.h @@ -174,7 +174,7 @@ public: virtual void SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob, + Blob* aBlob, BluetoothReplyRunnable* aRunnable) override; virtual void diff --git a/dom/bluetooth/bluez/BluetoothOppManager.cpp b/dom/bluetooth/bluez/BluetoothOppManager.cpp index e79069fe107..a36be8386d5 100644 --- a/dom/bluetooth/bluez/BluetoothOppManager.cpp +++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp @@ -73,16 +73,17 @@ namespace { static bool sInShutdown = false; } -class mozilla::dom::bluetooth::SendFileBatch { +class mozilla::dom::bluetooth::SendFileBatch +{ public: - SendFileBatch(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob) + SendFileBatch(const nsAString& aDeviceAddress, Blob* aBlob) : mDeviceAddress(aDeviceAddress) { mBlobs.AppendElement(aBlob); } nsString mDeviceAddress; - nsCOMArray mBlobs; + nsTArray> mBlobs; }; NS_IMETHODIMP @@ -385,14 +386,14 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress, MOZ_ASSERT(NS_IsMainThread()); nsRefPtr impl = aActor->GetBlobImpl(); - nsCOMPtr blob = Blob::Create(nullptr, impl); + nsRefPtr blob = Blob::Create(nullptr, impl); - return SendFile(aDeviceAddress, blob.get()); + return SendFile(aDeviceAddress, blob); } bool BluetoothOppManager::SendFile(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob) + Blob* aBlob) { MOZ_ASSERT(NS_IsMainThread()); @@ -406,7 +407,7 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress, void BluetoothOppManager::AppendBlobToSend(const nsAString& aDeviceAddress, - nsIDOMBlob* aBlob) + Blob* aBlob) { MOZ_ASSERT(NS_IsMainThread()); @@ -766,7 +767,7 @@ BluetoothOppManager::RetrieveSentFileName() { mFileName.Truncate(); - nsCOMPtr file = do_QueryInterface(mBlob); + nsRefPtr file = mBlob->ToFile(); if (file) { file->GetName(mFileName); } diff --git a/dom/bluetooth/bluez/BluetoothOppManager.h b/dom/bluetooth/bluez/BluetoothOppManager.h index e0149f254d1..f7cfe2afeb1 100644 --- a/dom/bluetooth/bluez/BluetoothOppManager.h +++ b/dom/bluetooth/bluez/BluetoothOppManager.h @@ -14,13 +14,13 @@ #include "mozilla/ipc/SocketBase.h" #include "nsCOMArray.h" -class nsIDOMBlob; class nsIOutputStream; class nsIInputStream; class nsIVolumeMountLock; namespace mozilla { namespace dom { +class Blob; class BlobParent; } } @@ -51,7 +51,7 @@ public: bool Listen(); bool SendFile(const nsAString& aDeviceAddress, BlobParent* aActor); - bool SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob); + bool SendFile(const nsAString& aDeviceAddress, Blob* aBlob); bool StopSendingFile(); bool ConfirmReceivingFile(bool aConfirm); @@ -96,7 +96,7 @@ private: void NotifyAboutFileChange(); bool AcquireSdcardMountLock(); void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize); - void AppendBlobToSend(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob); + void AppendBlobToSend(const nsAString& aDeviceAddress, Blob* aBlob); void DiscardBlobsToSend(); bool ProcessNextBatch(); void ConnectInternal(const nsAString& aDeviceAddress); @@ -193,7 +193,7 @@ private: nsAutoArrayPtr mReceivedDataBuffer; int mCurrentBlobIndex; - nsCOMPtr mBlob; + nsRefPtr mBlob; nsTArray mBatches; /** diff --git a/dom/fetch/InternalResponse.cpp b/dom/fetch/InternalResponse.cpp index 6d7c1125b4d..6ee065c7bc3 100644 --- a/dom/fetch/InternalResponse.cpp +++ b/dom/fetch/InternalResponse.cpp @@ -6,8 +6,6 @@ #include "InternalResponse.h" -#include "nsIDOMFile.h" - #include "mozilla/dom/InternalHeaders.h" #include "nsStreamUtils.h" #include "nsSerializationHelper.h" diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp index 85992ced064..e3fbbb61962 100644 --- a/dom/html/HTMLCanvasElement.cpp +++ b/dom/html/HTMLCanvasElement.cpp @@ -647,16 +647,22 @@ HTMLCanvasElement::MozGetAsFile(const nsAString& aName, const nsAString& aType, ErrorResult& aRv) { - nsCOMPtr file; + nsCOMPtr file; aRv = MozGetAsFile(aName, aType, getter_AddRefs(file)); - nsRefPtr tmp = static_cast(file.get()); - return tmp.forget(); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + nsCOMPtr blob = do_QueryInterface(file); + nsRefPtr domBlob = static_cast(blob.get()); + MOZ_ASSERT(domBlob->IsFile()); + return domBlob->ToFile(); } NS_IMETHODIMP HTMLCanvasElement::MozGetAsFile(const nsAString& aName, const nsAString& aType, - nsIDOMFile** aResult) + nsISupports** aResult) { OwnerDoc()->WarnOnceAbout(nsIDocument::eMozGetAsFile); @@ -672,7 +678,7 @@ HTMLCanvasElement::MozGetAsFile(const nsAString& aName, nsresult HTMLCanvasElement::MozGetAsBlobImpl(const nsAString& aName, const nsAString& aType, - nsIDOMFile** aResult) + nsISupports** aResult) { nsCOMPtr stream; nsAutoString type(aType); @@ -696,7 +702,7 @@ HTMLCanvasElement::MozGetAsBlobImpl(const nsAString& aName, nsCOMPtr win = do_QueryInterface(OwnerDoc()->GetScopeObject()); // The File takes ownership of the buffer - nsRefPtr file = + nsCOMPtr file = File::CreateMemoryFile(win, imgData, (uint32_t)imgSize, aName, type, PR_Now()); diff --git a/dom/html/HTMLCanvasElement.h b/dom/html/HTMLCanvasElement.h index 5da35892100..fa28265f155 100644 --- a/dom/html/HTMLCanvasElement.h +++ b/dom/html/HTMLCanvasElement.h @@ -237,7 +237,7 @@ protected: nsAString& aDataURL); nsresult MozGetAsBlobImpl(const nsAString& aName, const nsAString& aType, - nsIDOMFile** aResult); + nsISupports** aResult); void CallPrintCallback(); CanvasContextType mCurrentContextType; diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 2b2ebafdff2..e7f2c876681 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -405,7 +405,9 @@ public: MOZ_ASSERT(blobImpl); blobImpl->SetPath(Substring(path, 0, uint32_t(length))); } - *aResult = domFile.forget().downcast().take(); + + nsCOMPtr blob = domFile.get(); + blob.forget(aResult); LookupAndCacheNext(); return NS_OK; } @@ -488,23 +490,28 @@ NS_IMPL_ISUPPORTS(DirPickerRecursiveFileEnumerator, nsISimpleEnumerator) /** * This may return nullptr if aDomFile's implementation of - * nsIDOMFile::mozFullPathInternal does not successfully return a non-empty + * File::mozFullPathInternal does not successfully return a non-empty * string that is a valid path. This can happen on Firefox OS, for example, * where the file picker can create Blobs. */ static already_AddRefed -DOMFileToLocalFile(nsIDOMFile* aDomFile) +DOMFileToLocalFile(File* aDomFile) { nsString path; - nsresult rv = aDomFile->GetMozFullPathInternal(path); - if (NS_FAILED(rv) || path.IsEmpty()) { + ErrorResult rv; + aDomFile->GetMozFullPathInternal(path, rv); + if (rv.Failed() || path.IsEmpty()) { + rv.SuppressException(); return nullptr; } nsCOMPtr localFile; rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true, getter_AddRefs(localFile)); - NS_ENSURE_SUCCESS(rv, nullptr); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + return nullptr; + } return localFile.forget(); } @@ -532,9 +539,9 @@ public: nsCOMPtr tmp; while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) { iter->GetNext(getter_AddRefs(tmp)); - nsCOMPtr domFile = do_QueryInterface(tmp); - MOZ_ASSERT(domFile); - mFileList.AppendElement(static_cast(domFile.get())); + nsCOMPtr domBlob = do_QueryInterface(tmp); + MOZ_ASSERT(domBlob); + mFileList.AppendElement(static_cast(domBlob.get())); mFileListLength = mFileList.Length(); if (mCanceled) { MOZ_ASSERT(!mInput, "This is bad - how did this happen?"); @@ -691,20 +698,23 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult) while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) { iter->GetNext(getter_AddRefs(tmp)); - nsCOMPtr domFile = do_QueryInterface(tmp); - NS_WARN_IF_FALSE(domFile, + nsCOMPtr domBlob = do_QueryInterface(tmp); + NS_WARN_IF_FALSE(domBlob, "Null file object from FilePicker's file enumerator?"); - if (domFile) { - newFiles.AppendElement(static_cast(domFile.get())); + if (domBlob) { + newFiles.AppendElement(static_cast(domBlob.get())); } } } else { MOZ_ASSERT(mode == static_cast(nsIFilePicker::modeOpen)); - nsCOMPtr domFile; - nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(domFile)); + nsCOMPtr tmp; + nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(tmp)); NS_ENSURE_SUCCESS(rv, rv); - if (domFile) { - newFiles.AppendElement(static_cast(domFile.get())); + + nsCOMPtr blob = do_QueryInterface(tmp); + if (blob) { + nsRefPtr file = static_cast(blob.get())->ToFile(); + newFiles.AppendElement(file); } } @@ -969,7 +979,11 @@ HTMLInputElement::InitFilePicker(FilePickerType aType) aType != FILE_PICKER_DIRECTORY) { nsString path; - oldFiles[0]->GetMozFullPathInternal(path); + ErrorResult error; + oldFiles[0]->GetMozFullPathInternal(path, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } nsCOMPtr localFile; rv = NS_NewLocalFile(path, false, getter_AddRefs(localFile)); @@ -1708,7 +1722,12 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const // XXX We'd love to assert that this can't happen, but some mochitests // use SpecialPowers to circumvent our more sane security model. if (!mFiles.IsEmpty()) { - return mFiles[0]->GetMozFullPath(aValue); + ErrorResult rv; + mFiles[0]->GetMozFullPath(aValue, rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + return NS_OK; } else { aValue.Truncate(); @@ -1716,8 +1735,10 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const #endif } else { // Just return the leaf name - if (mFiles.IsEmpty() || NS_FAILED(mFiles[0]->GetName(aValue))) { + if (mFiles.IsEmpty()) { aValue.Truncate(); + } else { + mFiles[0]->GetName(aValue); } } @@ -2307,11 +2328,16 @@ HTMLInputElement::FlushFrames() } void -HTMLInputElement::MozGetFileNameArray(nsTArray< nsString >& aArray) +HTMLInputElement::MozGetFileNameArray(nsTArray& aArray, + ErrorResult& aRv) { for (uint32_t i = 0; i < mFiles.Length(); i++) { nsString str; - mFiles[i]->GetMozFullPathInternal(str); + mFiles[i]->GetMozFullPathInternal(str, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + aArray.AppendElement(str); } } @@ -2326,8 +2352,12 @@ HTMLInputElement::MozGetFileNameArray(uint32_t* aLength, char16_t*** aFileNames) return NS_ERROR_DOM_SECURITY_ERR; } + ErrorResult rv; nsTArray array; - MozGetFileNameArray(array); + MozGetFileNameArray(array, rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } *aLength = array.Length(); char16_t** ret = @@ -2687,7 +2717,11 @@ HTMLInputElement::AfterSetFiles(bool aSetValueChanged) if (mFiles.IsEmpty()) { mFirstFilePath.Truncate(); } else { - mFiles[0]->GetMozFullPath(mFirstFilePath); + ErrorResult rv; + mFiles[0]->GetMozFullPath(mFirstFilePath, rv); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + } } #endif diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 740c2bdf466..7cc9649555f 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -713,7 +713,7 @@ public: int32_t GetTextLength(ErrorResult& aRv); - void MozGetFileNameArray(nsTArray< nsString >& aFileNames); + void MozGetFileNameArray(nsTArray& aFileNames, ErrorResult& aRv); void MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv); void MozSetFileArray(const Sequence>& aFiles); diff --git a/dom/html/nsFormSubmission.cpp b/dom/html/nsFormSubmission.cpp index 428d7e3456e..93ae02ccc62 100644 --- a/dom/html/nsFormSubmission.cpp +++ b/dom/html/nsFormSubmission.cpp @@ -18,7 +18,6 @@ #include "nsAttrValueInlines.h" #include "nsISaveAsCharset.h" #include "nsIFile.h" -#include "nsIDOMFile.h" #include "nsDirectoryServiceDefs.h" #include "nsStringStream.h" #include "nsIURI.h" @@ -451,15 +450,13 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName, nsCOMPtr fileStream; if (aFile) { nsAutoString filename16; - rv = aFile->GetName(filename16); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } + aFile->GetName(filename16); + ErrorResult error; nsAutoString filepath16; - rv = aFile->GetPath(filepath16); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; + aFile->GetPath(filepath16, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); } if (!filepath16.IsEmpty()) { diff --git a/dom/indexedDB/IDBMutableFile.cpp b/dom/indexedDB/IDBMutableFile.cpp index b7dd0ce53cb..fd84c2ce315 100644 --- a/dom/indexedDB/IDBMutableFile.cpp +++ b/dom/indexedDB/IDBMutableFile.cpp @@ -27,7 +27,6 @@ #include "nsContentUtils.h" #include "nsDebug.h" #include "nsError.h" -#include "nsIDOMFile.h" #include "nsIPrincipal.h" namespace mozilla { @@ -328,7 +327,7 @@ IDBMutableFile::GetFileId() const return mFileInfo->Id(); } -already_AddRefed +already_AddRefed IDBMutableFile::CreateFileObject(IDBFileHandle* aFileHandle, MetadataParameters* aMetadataParams) { @@ -393,12 +392,10 @@ GetFileHelper::GetSuccessResult(JSContext* aCx, auto fileHandle = static_cast(mFileHandle.get()); - nsCOMPtr domFile = + nsRefPtr domFile = mMutableFile->CreateFileObject(fileHandle, mParams); - nsresult rv = - nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile), aVal); - if (NS_WARN_IF(NS_FAILED(rv))) { + if (!ToJSValue(aCx, domFile, aVal)) { return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR; } diff --git a/dom/indexedDB/IDBMutableFile.h b/dom/indexedDB/IDBMutableFile.h index ca26c78908c..45f78b9c67d 100644 --- a/dom/indexedDB/IDBMutableFile.h +++ b/dom/indexedDB/IDBMutableFile.h @@ -18,7 +18,6 @@ #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" -class nsIDOMFile; class nsPIDOMWindow; namespace mozilla { @@ -28,6 +27,7 @@ class ErrorResult; namespace dom { class DOMRequest; +class File; class MetadataParameters; namespace indexedDB { @@ -83,7 +83,7 @@ public: return mFileInfo; } - already_AddRefed + already_AddRefed CreateFileObject(IDBFileHandle* aFileHandle, MetadataParameters* aMetadataParams); diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index ba64714f4ea..802f6f6e272 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -334,14 +334,14 @@ StructuredCloneWriteCallback(JSContext* aCx, nsRefPtr file = blob->ToFile(); if (file) { - int64_t lastModifiedDate; - MOZ_ALWAYS_TRUE(NS_SUCCEEDED( - file->GetMozLastModifiedDate(&lastModifiedDate))); + ErrorResult rv; + int64_t lastModifiedDate = file->GetLastModified(rv); + MOZ_ALWAYS_TRUE(!rv.Failed()); lastModifiedDate = NativeEndian::swapToLittleEndian(lastModifiedDate); nsString name; - MOZ_ALWAYS_TRUE(NS_SUCCEEDED(file->GetName(name))); + file->GetName(name); NS_ConvertUTF16toUTF8 convName(name); uint32_t convNameLength = diff --git a/dom/indexedDB/IDBTransaction.cpp b/dom/indexedDB/IDBTransaction.cpp index c93b8ea9590..90d6f2820a5 100644 --- a/dom/indexedDB/IDBTransaction.cpp +++ b/dom/indexedDB/IDBTransaction.cpp @@ -17,7 +17,6 @@ #include "mozilla/dom/DOMStringList.h" #include "mozilla/ipc/BackgroundChild.h" #include "nsIAppShell.h" -#include "nsIDOMFile.h" #include "nsPIDOMWindow.h" #include "nsServiceManagerUtils.h" #include "nsTHashtable.h" diff --git a/dom/indexedDB/test/file.js b/dom/indexedDB/test/file.js index db0761910d3..ae63af38f99 100644 --- a/dom/indexedDB/test/file.js +++ b/dom/indexedDB/test/file.js @@ -94,12 +94,11 @@ function verifyBlob(blob1, blob2, fileId, blobReadHandler) { is(blob1 instanceof Components.interfaces.nsIDOMBlob, true, "Instance of nsIDOMBlob"); - is(blob1 instanceof Components.interfaces.nsIDOMFile, - blob2 instanceof Components.interfaces.nsIDOMFile, - "Instance of nsIDOMFile"); + is(blob1 instanceof File, blob2 instanceof File, + "Instance of DOM File"); is(blob1.size, blob2.size, "Correct size"); is(blob1.type, blob2.type, "Correct type"); - if (blob2 instanceof Components.interfaces.nsIDOMFile) { + if (blob2 instanceof File) { is(blob1.name, blob2.name, "Correct name"); } is(utils.getFileId(blob1), fileId, "Correct file id"); diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index 22e545baec7..fcfb1250f12 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -39,8 +39,6 @@ interface nsIDOMStyleSheet; interface nsITransferable; interface nsIQueryContentEventResult; interface nsIDOMWindow; -interface nsIDOMBlob; -interface nsIDOMFile; interface nsIFile; interface nsIDOMClientRect; interface nsIURI; @@ -51,7 +49,7 @@ interface nsIJSRAIIHelper; interface nsIContentPermissionRequest; interface nsIObserver; -[scriptable, uuid(1a75c351-d115-4d51-94df-731dd1723a1f)] +[scriptable, uuid(34a42cdc-7a04-4e71-8a5c-63e092fba58e)] interface nsIDOMWindowUtils : nsISupports { /** @@ -1445,9 +1443,10 @@ interface nsIDOMWindowUtils : nsISupports { in AString value2); /** - * Wrap an nsIFile in an nsIDOMFile + * Wrap an nsIFile in an DOM File + * Returns a File object. */ - nsIDOMFile wrapDOMFile(in nsIFile aFile); + nsISupports wrapDOMFile(in nsIFile aFile); /** * Get the type of the currently focused html input, if any. diff --git a/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl b/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl index 3ec838bb592..eaccc631b02 100644 --- a/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl +++ b/dom/interfaces/html/nsIDOMHTMLCanvasElement.idl @@ -16,11 +16,10 @@ */ interface nsIDOMBlob; -interface nsIDOMFile; interface nsIVariant; interface nsIInputStreamCallback; -[uuid(8978d1c5-2981-4678-a1c3-b0b7bae04fbc)] +[uuid(2c984658-2e7c-4774-8ac5-cf1b39f8bec3)] interface nsIDOMHTMLCanvasElement : nsISupports { attribute unsigned long width; @@ -38,7 +37,8 @@ interface nsIDOMHTMLCanvasElement : nsISupports // Valid calls are // mozGetAsFile(name); -- defaults to image/png // mozGetAsFile(name, type); -- uses given type - nsIDOMFile mozGetAsFile(in DOMString name, [optional] in DOMString type); + // The return value is a File object. + nsISupports mozGetAsFile(in DOMString name, [optional] in DOMString type); // A Mozilla-only extension to get a canvas context backed by double-buffered // shared memory. Only privileged callers can call this. diff --git a/dom/ipc/Blob.cpp b/dom/ipc/Blob.cpp index e2584a8aa72..054d39bff12 100644 --- a/dom/ipc/Blob.cpp +++ b/dom/ipc/Blob.cpp @@ -2064,8 +2064,8 @@ public: virtual void GetName(nsAString& aName) override; - virtual nsresult - GetPath(nsAString& aPath) override; + virtual void + GetPath(nsAString& aPath, ErrorResult& aRv) override; virtual int64_t GetLastModified(ErrorResult& aRv) override; @@ -2742,11 +2742,11 @@ RemoteBlobImpl::GetName(nsAString& aName) mBlobImpl->GetName(aName); } -nsresult +void BlobParent:: -RemoteBlobImpl::GetPath(nsAString& aPath) +RemoteBlobImpl::GetPath(nsAString& aPath, ErrorResult& aRv) { - return mBlobImpl->GetPath(aPath); + mBlobImpl->GetPath(aPath, aRv); } int64_t diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp index eee1793eadf..f30e52be679 100644 --- a/dom/ipc/ContentProcess.cpp +++ b/dom/ipc/ContentProcess.cpp @@ -10,6 +10,7 @@ #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) #include "mozilla/Preferences.h" +#include "mozilla/WindowsVersion.h" #include "nsDirectoryService.h" #include "nsDirectoryServiceDefs.h" #endif @@ -20,74 +21,100 @@ namespace mozilla { namespace dom { #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) -static already_AddRefed -GetLowIntegrityTemp() -{ - MOZ_ASSERT(nsDirectoryService::gService, - "GetLowIntegrityTemp relies on nsDirectoryService being initialized"); - - // A low integrity temp only currently makes sense for sandbox pref level 1. - if (Preferences::GetInt("security.sandbox.content.level") != 1) { - return nullptr; - } - - nsCOMPtr lowIntegrityTemp; - nsresult rv = nsDirectoryService::gService->Get(NS_WIN_LOW_INTEGRITY_TEMP, - NS_GET_IID(nsIFile), - getter_AddRefs(lowIntegrityTemp)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nullptr; - } - - return lowIntegrityTemp.forget(); -} - static void SetUpSandboxEnvironment() { MOZ_ASSERT(nsDirectoryService::gService, "SetUpSandboxEnvironment relies on nsDirectoryService being initialized"); - // Setup to use a low integrity temp if available. - nsCOMPtr lowIntegrityTemp = GetLowIntegrityTemp(); - if (!lowIntegrityTemp) { + // A low integrity temp only currently makes sense for Vista or Later and + // sandbox pref level 1. + if (!IsVistaOrLater() || + Preferences::GetInt("security.sandbox.content.level") != 1) { return; } + nsAdoptingString tempDirSuffix = + Preferences::GetString("security.sandbox.content.tempDirSuffix"); + if (tempDirSuffix.IsEmpty()) { + NS_WARNING("Low integrity temp suffix pref not set."); + return; + } + + // Get the base low integrity Mozilla temp directory. + nsCOMPtr lowIntegrityTemp; + nsresult rv = nsDirectoryService::gService->Get(NS_WIN_LOW_INTEGRITY_TEMP_BASE, + NS_GET_IID(nsIFile), + getter_AddRefs(lowIntegrityTemp)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + // Append our profile specific temp name. + rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + // Change the gecko defined temp directory to our low integrity one. // Undefine returns a failure if the property is not already set. unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR); - nsresult rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp); + rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp); if (NS_WARN_IF(NS_FAILED(rv))) { return; } - - // Set TEMP and TMP environment variables. - nsAutoString lowIntegrityTempPath; - rv = lowIntegrityTemp->GetPath(lowIntegrityTempPath); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - bool setOK = SetEnvironmentVariableW(L"TEMP", lowIntegrityTempPath.get()); - NS_WARN_IF_FALSE(setOK, "Failed to set TEMP to low integrity temp path"); - setOK = SetEnvironmentVariableW(L"TMP", lowIntegrityTempPath.get()); - NS_WARN_IF_FALSE(setOK, "Failed to set TMP to low integrity temp path"); } +#if defined(NIGHTLY_BUILD) static void -CleanUpSandboxEnvironment() +CleanUpOldSandboxEnvironment() { - // Remove low integrity temp if it exists. - nsCOMPtr lowIntegrityTemp = GetLowIntegrityTemp(); - if (!lowIntegrityTemp) { + // Temporary code to clean up the old low integrity temp directories. + // The removal of this is tracked by bug 1165818. + nsCOMPtr lowIntegrityMozilla; + nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOCAL_APPDATA_LOW_DIR, + getter_AddRefs(lowIntegrityMozilla)); + if (NS_WARN_IF(NS_FAILED(rv))) { return; } - // Don't check the return value as the directory will only have been created - // if it has been used. - unused << lowIntegrityTemp->Remove(/* aRecursive */ true); + rv = lowIntegrityMozilla->Append(NS_LITERAL_STRING(MOZ_USER_DIR)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsCOMPtr iter; + rv = lowIntegrityMozilla->GetDirectoryEntries(getter_AddRefs(iter)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + bool more; + nsCOMPtr elem; + while (NS_SUCCEEDED(iter->HasMoreElements(&more)) && more) { + rv = iter->GetNext(getter_AddRefs(elem)); + if (NS_FAILED(rv)) { + break; + } + + nsCOMPtr file = do_QueryInterface(elem); + if (!file) { + continue; + } + + nsAutoString leafName; + rv = file->GetLeafName(leafName); + if (NS_FAILED(rv)) { + continue; + } + + if (leafName.Find(NS_LITERAL_STRING("MozTemp-{")) == 0) { + file->Remove(/* aRecursive */ true); + } + } } #endif +#endif void ContentProcess::SetAppDir(const nsACString& aPath) @@ -114,8 +141,8 @@ ContentProcess::Init() void ContentProcess::CleanUp() { -#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) - CleanUpSandboxEnvironment(); +#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) && defined(NIGHTLY_BUILD) + CleanUpOldSandboxEnvironment(); #endif mXREEmbed.Stop(); } diff --git a/dom/ipc/FilePickerParent.cpp b/dom/ipc/FilePickerParent.cpp index e1d48ce97b1..3ee1189045a 100644 --- a/dom/ipc/FilePickerParent.cpp +++ b/dom/ipc/FilePickerParent.cpp @@ -8,7 +8,6 @@ #include "nsComponentManagerUtils.h" #include "nsNetCID.h" #include "nsIDocument.h" -#include "nsIDOMFile.h" #include "nsIDOMWindow.h" #include "nsIFile.h" #include "nsISimpleEnumerator.h" diff --git a/dom/ipc/FilePickerParent.h b/dom/ipc/FilePickerParent.h index 7a2f0e896ed..72cc41dc099 100644 --- a/dom/ipc/FilePickerParent.h +++ b/dom/ipc/FilePickerParent.h @@ -7,7 +7,6 @@ #ifndef mozilla_dom_FilePickerParent_h #define mozilla_dom_FilePickerParent_h -#include "nsIDOMFile.h" #include "nsIEventTarget.h" #include "nsIFilePicker.h" #include "nsCOMArray.h" diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp index 1ccaf24b629..e4ceb41848c 100644 --- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -901,6 +901,7 @@ MediaFormatReader::Update(TrackType aTrack) LOGV("Update(%s) ni=%d no=%d", TrackTypeToStr(aTrack), needInput, needOutput); if (decoder.mDemuxEOS && !decoder.mDemuxEOSServiced) { + decoder.mOutputRequested = true; decoder.mDecoder->Drain(); decoder.mDemuxEOSServiced = true; } diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index f33d1a2f936..e849a7c6cc5 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -113,6 +113,7 @@ GetMediaManagerLog() } #define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg) +using dom::File; using dom::MediaStreamConstraints; using dom::MediaTrackConstraintSet; using dom::MediaTrackConstraints; @@ -264,53 +265,6 @@ private: nsRefPtr mManager; // get ref to this when creating the runnable }; -/** - * Invoke the "onSuccess" callback in content. The callback will take a - * DOMBlob in the case of {picture:true}, and a MediaStream in the case of - * {audio:true} or {video:true}. There is a constructor available for each - * form. Do this only on the main thread. - */ -class SuccessCallbackRunnable : public nsRunnable -{ -public: - SuccessCallbackRunnable( - nsCOMPtr& aOnSuccess, - nsCOMPtr& aOnFailure, - nsIDOMFile* aFile, uint64_t aWindowID) - : mFile(aFile) - , mWindowID(aWindowID) - , mManager(MediaManager::GetInstance()) - { - mOnSuccess.swap(aOnSuccess); - mOnFailure.swap(aOnFailure); - } - - NS_IMETHOD - Run() - { - // Only run if the window is still active. - NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); - - nsCOMPtr onSuccess = mOnSuccess.forget(); - nsCOMPtr onFailure = mOnFailure.forget(); - - if (!(mManager->IsWindowStillActive(mWindowID))) { - return NS_OK; - } - // This is safe since we're on main-thread, and the windowlist can only - // be invalidated from the main-thread (see OnNavigation) - onSuccess->OnSuccess(mFile); - return NS_OK; - } - -private: - nsCOMPtr mOnSuccess; - nsCOMPtr mOnFailure; - nsCOMPtr mFile; - uint64_t mWindowID; - nsRefPtr mManager; // get ref to this when creating the runnable -}; - /** * Invoke the GetUserMediaDevices success callback. Wrapped in a runnable * so that it may be called on the main thread. The error callback is also diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.h b/dom/media/webrtc/MediaEngineGonkVideoSource.h index b072f193f5f..bfa12293f76 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.h +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.h @@ -112,7 +112,7 @@ protected: mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling // This is only modified on MainThread (AllocImpl and DeallocImpl) nsRefPtr mCameraControl; - nsCOMPtr mLastCapture; + nsRefPtr mLastCapture; android::sp mCameraSource; diff --git a/dom/nfc/nsINfcContentHelper.idl b/dom/nfc/nsINfcContentHelper.idl index 0454bf8636a..fc172fcad05 100644 --- a/dom/nfc/nsINfcContentHelper.idl +++ b/dom/nfc/nsINfcContentHelper.idl @@ -210,7 +210,7 @@ interface nsINfcContentHelper : nsISupports * * @param blob * Raw data of the file to be sent. This object represents a file-like - * (nsIDOMFile) object of immutable, raw data. The blob data needs + * (DOM File) object of immutable, raw data. The blob data needs * to be 'object wrapped' before calling this interface. * * @param sessionToken diff --git a/dom/push/PushService.jsm b/dom/push/PushService.jsm index ff8e24b729f..fa270ca78b1 100644 --- a/dom/push/PushService.jsm +++ b/dom/push/PushService.jsm @@ -89,151 +89,161 @@ this.PushDB.prototype = { /* * @param aChannelRecord * The record to be added. - * @param aSuccessCb - * Callback function to invoke with result ID. - * @param aErrorCb [optional] - * Callback function to invoke when there was an error. */ - put: function(aChannelRecord, aSuccessCb, aErrorCb) { + put: function(aChannelRecord) { debug("put()" + JSON.stringify(aChannelRecord)); - this.newTxn( - "readwrite", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - debug("Going to put " + aChannelRecord.channelID); - aStore.put(aChannelRecord).onsuccess = function setTxnResult(aEvent) { - debug("Request successful. Updated record ID: " + - aEvent.target.result); - }; - }, - aSuccessCb, - aErrorCb + return new Promise((resolve, reject) => + this.newTxn( + "readwrite", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + debug("Going to put " + aChannelRecord.channelID); + aStore.put(aChannelRecord).onsuccess = function setTxnResult(aEvent) { + debug("Request successful. Updated record ID: " + + aEvent.target.result); + }; + }, + resolve, + reject + ) ); }, /* * @param aChannelID * The ID of record to be deleted. - * @param aSuccessCb - * Callback function to invoke with result. - * @param aErrorCb [optional] - * Callback function to invoke when there was an error. + */ - delete: function(aChannelID, aSuccessCb, aErrorCb) { + delete: function(aChannelID) { debug("delete()"); - this.newTxn( - "readwrite", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - debug("Going to delete " + aChannelID); - aStore.delete(aChannelID); - }, - aSuccessCb, - aErrorCb + return new Promise((resolve, reject) => + this.newTxn( + "readwrite", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + debug("Going to delete " + aChannelID); + aStore.delete(aChannelID); + }, + resolve, + reject + ) ); }, - clearAll: function clear(aSuccessCb, aErrorCb) { - this.newTxn( - "readwrite", - kPUSHDB_STORE_NAME, - function (aTxn, aStore) { - debug("Going to clear all!"); - aStore.clear(); - }, - aSuccessCb, - aErrorCb + clearAll: function clear() { + return new Promise((resolve, reject) => + this.newTxn( + "readwrite", + kPUSHDB_STORE_NAME, + function (aTxn, aStore) { + debug("Going to clear all!"); + aStore.clear(); + }, + resolve, + reject + ) ); }, - getByPushEndpoint: function(aPushEndpoint, aSuccessCb, aErrorCb) { + getByPushEndpoint: function(aPushEndpoint) { debug("getByPushEndpoint()"); - this.newTxn( - "readonly", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - aTxn.result = undefined; + return new Promise((resolve, reject) => + this.newTxn( + "readonly", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + aTxn.result = undefined; - let index = aStore.index("pushEndpoint"); - index.get(aPushEndpoint).onsuccess = function setTxnResult(aEvent) { - aTxn.result = aEvent.target.result; - debug("Fetch successful " + aEvent.target.result); - } - }, - aSuccessCb, - aErrorCb + let index = aStore.index("pushEndpoint"); + index.get(aPushEndpoint).onsuccess = function setTxnResult(aEvent) { + aTxn.result = aEvent.target.result; + debug("Fetch successful " + aEvent.target.result); + } + }, + resolve, + reject + ) ); }, - getByChannelID: function(aChannelID, aSuccessCb, aErrorCb) { + getByChannelID: function(aChannelID) { debug("getByChannelID()"); - this.newTxn( - "readonly", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - aTxn.result = undefined; + return new Promise((resolve, reject) => + this.newTxn( + "readonly", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + aTxn.result = undefined; - aStore.get(aChannelID).onsuccess = function setTxnResult(aEvent) { - aTxn.result = aEvent.target.result; - debug("Fetch successful " + aEvent.target.result); - } - }, - aSuccessCb, - aErrorCb + aStore.get(aChannelID).onsuccess = function setTxnResult(aEvent) { + aTxn.result = aEvent.target.result; + debug("Fetch successful " + aEvent.target.result); + } + }, + resolve, + reject + ) ); }, - getByScope: function(aScope, aSuccessCb, aErrorCb) { + getByScope: function(aScope) { debug("getByScope() " + aScope); - this.newTxn( - "readonly", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - aTxn.result = undefined; + return new Promise((resolve, reject) => + this.newTxn( + "readonly", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + aTxn.result = undefined; - let index = aStore.index("scope"); - index.get(aScope).onsuccess = function setTxnResult(aEvent) { - aTxn.result = aEvent.target.result; - debug("Fetch successful " + aEvent.target.result); - } - }, - aSuccessCb, - aErrorCb + let index = aStore.index("scope"); + index.get(aScope).onsuccess = function setTxnResult(aEvent) { + aTxn.result = aEvent.target.result; + debug("Fetch successful " + aEvent.target.result); + } + }, + resolve, + reject + ) ); }, - getAllChannelIDs: function(aSuccessCb, aErrorCb) { + getAllChannelIDs: function() { debug("getAllChannelIDs()"); - this.newTxn( - "readonly", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - aStore.mozGetAll().onsuccess = function(event) { - aTxn.result = event.target.result; - } - }, - aSuccessCb, - aErrorCb + return new Promise((resolve, reject) => + this.newTxn( + "readonly", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + aStore.mozGetAll().onsuccess = function(event) { + aTxn.result = event.target.result; + } + }, + resolve, + reject + ) ); }, - drop: function(aSuccessCb, aErrorCb) { + drop: function() { debug("drop()"); - this.newTxn( - "readwrite", - kPUSHDB_STORE_NAME, - function txnCb(aTxn, aStore) { - aStore.clear(); - }, - aSuccessCb, - aErrorCb + + return new Promise((resolve, reject) => + this.newTxn( + "readwrite", + kPUSHDB_STORE_NAME, + function txnCb(aTxn, aStore) { + aStore.clear(); + }, + resolve, + reject + ) ); } }; @@ -400,21 +410,31 @@ this.PushService = { return; } - this._db.getByScope(scope, function(record) { - this._db.delete(records.channelID, null, function() { - debug("webapps-clear-data: " + scope + - " Could not delete entry " + records.channelID); + this._db.getByScope(scope) + .then(record => { + this._db.delete(records.channelID) + .then(_ => { + // courtesy, but don't establish a connection + // just for it + if (this._ws) { + debug("Had a connection, so telling the server"); + this._send("unregister", {channelID: records.channelID}); + } + }, err => { + debug("webapps-clear-data: " + scope + + " Could not delete entry " + records.channelID); - // courtesy, but don't establish a connection - // just for it - if (this._ws) { - debug("Had a connection, so telling the server"); - this._send("unregister", {channelID: records.channelID}); - } - }.bind(this), function() { + // courtesy, but don't establish a connection + // just for it + if (this._ws) { + debug("Had a connection, so telling the server"); + this._send("unregister", {channelID: records.channelID}); + } + throw "Database error"; + }); + }, _ => { debug("webapps-clear-data: Error in getByScope(" + scope + ")"); }); - }); break; } @@ -954,11 +974,12 @@ this.PushService = { this._beginWSSetup(); return; } - this._db.getAllChannelIDs(function(channelIDs) { - if (channelIDs.length > 0) { - this._beginWSSetup(); - } - }.bind(this)); + this._db.getAllChannelIDs() + .then(channelIDs => { + if (channelIDs.length > 0) { + this._beginWSSetup(); + } + }); }, /** |delay| should be in milliseconds. */ @@ -1354,18 +1375,18 @@ this.PushService = { debug("Could not get channelID " + aChannelIDFromServer + " from DB"); } - this._db.getByChannelID(aChannelID, - compareRecordVersionAndNotify.bind(this), - recoverNoSuchChannelID.bind(this)); + this._db.getByChannelID(aChannelID) + .then(compareRecordVersionAndNotify.bind(this), + err => recoverNoSuchChannelID(err)); }, // Fires a push-register system message to all applications that have // registration. _notifyAllAppsRegister: function() { debug("notifyAllAppsRegister()"); - return new Promise((resolve, reject) => { - // records are objects describing the registration as stored in IndexedDB. - this._db.getAllChannelIDs(records => { + // records are objects describing the registration as stored in IndexedDB. + return this._db.getAllChannelIDs() + .then(records => { let scopes = new Set(); for (let record of records) { scopes.add(record.scope); @@ -1380,9 +1401,7 @@ this.PushService = { ); globalMM.broadcastAsyncMessage('pushsubscriptionchanged', scope); } - resolve(); - }, reject); - }); + }); }, _notifyApp: function(aPushRecord) { @@ -1428,15 +1447,11 @@ this.PushService = { _updatePushRecord: function(aPushRecord) { debug("updatePushRecord()"); - let deferred = Promise.defer(); - this._db.put(aPushRecord, deferred.resolve, deferred.reject); - return deferred.promise; + return this._db.put(aPushRecord); }, _dropRegistration: function() { - let deferred = Promise.defer(); - this._db.drop(deferred.resolve, deferred.reject); - return deferred.promise; + return this._db.drop(); }, receiveMessage: function(aMessage) { @@ -1474,11 +1489,8 @@ this.PushService = { }, _register: function(aPageRecord) { - let recordPromise = new Promise((resolve, reject) => - this._db.getByScope(aPageRecord.scope, resolve, reject)); - - return recordPromise.then( - pushRecord => { + return this._db.getByScope(aPageRecord.scope) + .then(pushRecord => { if (pushRecord == null) { let channelID = this._generateID(); return this._registerWithServer(channelID, aPageRecord); @@ -1603,33 +1615,24 @@ this.PushService = { _unregister: function(aPageRecord) { debug("unregisterWithServer()"); - let deferred = Promise.defer(); - let fail = function(error) { - debug("unregister() fail() error " + error); - deferred.reject(error); - }; - if (!aPageRecord.scope) { - fail("NotFoundError"); - return deferred.promise; + return Promise.reject("NotFoundError"); } - this._db.getByScope(aPageRecord.scope, function(record) { - // If the endpoint didn't exist, let's just fail. - if (record === undefined) { - fail("NotFoundError"); - return; - } + return this._db.getByScope(aPageRecord.scope) + .then(record => { + // If the endpoint didn't exist, let's just fail. + if (record === undefined) { + throw "NotFoundError"; + } - this._db.delete(record.channelID, function() { - // Let's be nice to the server and try to inform it, but we don't care - // about the reply. - this._send("unregister", {channelID: record.channelID}); - deferred.resolve(); - }.bind(this), fail); - }.bind(this), fail); - - return deferred.promise; + this._db.delete(record.channelID) + .then(_ => + // Let's be nice to the server and try to inform it, but we don't care + // about the reply. + this._send("unregister", {channelID: record.channelID}) + ); + }); }, unregister: function(aPageRecord, aMessageManager) { @@ -1652,23 +1655,19 @@ this.PushService = { }, _clearAll: function _clearAll() { - return new Promise((resolve, reject) => { - this._db.clearAll(() => resolve(), - () => reject("Database error")); - }); + return this._db.clearAll(); }, - + /** * Called on message from the child process */ _registration: function(aPageRecord) { - return new Promise((resolve, reject) => { - if (!aPageRecord.scope) { - reject("Database error"); - return; - } - this._db.getByScope(aPageRecord.scope, - pushRecord => { + if (!aPageRecord.scope) { + return Promise.reject("Database error"); + } + + return this._db.getByScope(aPageRecord.scope) + .then(pushRecord => { let registration = null; if (pushRecord) { registration = { @@ -1678,11 +1677,10 @@ this.PushService = { pushCount: pushRecord.pushCount }; } - resolve(registration); - }, - () => reject("Database error") - ); - }); + return registration; + }, _ => { + throw "Database error"; + }); }, registration: function(aPageRecord, aMessageManager) { @@ -1751,8 +1749,9 @@ this.PushService = { }; } - this._db.getAllChannelIDs(sendHelloMessage.bind(this), - sendHelloMessage.bind(this)); + this._db.getAllChannelIDs() + .then(sendHelloMessage.bind(this), + sendHelloMessage.bind(this)); }); }, diff --git a/dom/push/test/xpcshell/head.js b/dom/push/test/xpcshell/head.js index 7d5c3f70067..11bc2693de2 100644 --- a/dom/push/test/xpcshell/head.js +++ b/dom/push/test/xpcshell/head.js @@ -61,46 +61,6 @@ function after(times, func) { }; } -/** - * Wraps a Push database in a proxy that returns promises for all asynchronous - * methods. This makes it easier to test the database code with Task.jsm. - * - * @param {PushDB} db A Push database. - * @returns {Proxy} A proxy that traps function property gets and returns - * promisified functions. - */ -function promisifyDatabase(db) { - return new Proxy(db, { - get(target, property) { - let method = target[property]; - if (typeof method != 'function') { - return method; - } - return function(...params) { - return new Promise((resolve, reject) => { - method.call(target, ...params, resolve, reject); - }); - }; - } - }); -} - -/** - * Clears and closes an open Push database. - * - * @param {PushDB} db A Push database. - * @returns {Promise} A promise that fulfills when the database is closed. - */ -function cleanupDatabase(db) { - return new Promise(resolve => { - function close() { - db.close(); - resolve(); - } - db.drop(close, close); - }); -} - /** * Defers one or more callbacks until the next turn of the event loop. Multiple * callbacks are executed in order. diff --git a/dom/push/test/xpcshell/test_clearAll_successful.js b/dom/push/test/xpcshell/test_clearAll_successful.js index bf16f6434c6..e2bb5e2d34b 100644 --- a/dom/push/test/xpcshell/test_clearAll_successful.js +++ b/dom/push/test/xpcshell/test_clearAll_successful.js @@ -15,9 +15,8 @@ function run_test() { add_task(function* test_unregister_success() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); - yield promiseDB.put({ + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); + yield db.put({ channelID, pushEndpoint: 'https://example.org/update/unregister-success', scope: 'https://example.com/page/unregister-success', @@ -42,6 +41,6 @@ add_task(function* test_unregister_success() { }); yield PushNotificationService.clearAll(); - let record = yield promiseDB.getByChannelID(channelID); + let record = yield db.getByChannelID(channelID); ok(!record, 'Unregister did not remove record'); }); diff --git a/dom/push/test/xpcshell/test_notification_ack.js b/dom/push/test/xpcshell/test_notification_ack.js index 48fd90ab8e5..d0349f1df54 100644 --- a/dom/push/test/xpcshell/test_notification_ack.js +++ b/dom/push/test/xpcshell/test_notification_ack.js @@ -20,8 +20,7 @@ function run_test() { add_task(function* test_notification_ack() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let records = [{ channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c', pushEndpoint: 'https://example.com/update/1', @@ -39,7 +38,7 @@ add_task(function* test_notification_ack() { version: 3 }]; for (let record of records) { - yield promiseDB.put(record); + yield db.put(record); } let notifyPromise = Promise.all([ diff --git a/dom/push/test/xpcshell/test_notification_duplicate.js b/dom/push/test/xpcshell/test_notification_duplicate.js index 05af29d3660..ed857c6d224 100644 --- a/dom/push/test/xpcshell/test_notification_duplicate.js +++ b/dom/push/test/xpcshell/test_notification_duplicate.js @@ -18,8 +18,7 @@ function run_test() { // Should acknowledge duplicate notifications, but not notify apps. add_task(function* test_notification_duplicate() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let records = [{ channelID: '8d2d9400-3597-4c5a-8a38-c546b0043bcc', pushEndpoint: 'https://example.org/update/1', @@ -32,7 +31,7 @@ add_task(function* test_notification_duplicate() { version: 2 }]; for (let record of records) { - yield promiseDB.put(record); + yield db.put(record); } let notifyPromise = promiseObserverNotification('push-notification'); @@ -72,11 +71,11 @@ add_task(function* test_notification_duplicate() { yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, 'Timed out waiting for stale acknowledgement'); - let staleRecord = yield promiseDB.getByChannelID( + let staleRecord = yield db.getByChannelID( '8d2d9400-3597-4c5a-8a38-c546b0043bcc'); strictEqual(staleRecord.version, 2, 'Wrong stale record version'); - let updatedRecord = yield promiseDB.getByChannelID( + let updatedRecord = yield db.getByChannelID( '27d1e393-03ef-4c72-a5e6-9e890dfccad0'); strictEqual(updatedRecord.version, 3, 'Wrong updated record version'); }); diff --git a/dom/push/test/xpcshell/test_notification_error.js b/dom/push/test/xpcshell/test_notification_error.js index 5b5b64c849c..a68556a59cb 100644 --- a/dom/push/test/xpcshell/test_notification_error.js +++ b/dom/push/test/xpcshell/test_notification_error.js @@ -18,8 +18,7 @@ function run_test() { add_task(function* test_notification_error() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let records = [{ channelID: 'f04f1e46-9139-4826-b2d1-9411b0821283', pushEndpoint: 'https://example.org/update/success-1', @@ -37,7 +36,7 @@ add_task(function* test_notification_error() { version: 3 }]; for (let record of records) { - yield promiseDB.put(record); + yield db.put(record); } let notifyPromise = Promise.all([ @@ -56,11 +55,11 @@ add_task(function* test_notification_error() { PushService.init({ networkInfo: new MockDesktopNetworkInfo(), db: makeStub(db, { - getByChannelID(prev, channelID, successCb, failureCb) { + getByChannelID(prev, channelID) { if (channelID == '3c3930ba-44de-40dc-a7ca-8a133ec1a866') { - return failureCb('splines not reticulated'); + return Promise.reject('splines not reticulated'); } - return prev.call(this, channelID, successCb, failureCb); + return prev.call(this, channelID); } }), makeWebSocket(uri) { @@ -107,19 +106,19 @@ add_task(function* test_notification_error() { yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, 'Timed out waiting for acknowledgements'); - let aRecord = yield promiseDB.getByScope('https://example.com/a'); + let aRecord = yield db.getByScope('https://example.com/a'); equal(aRecord.channelID, 'f04f1e46-9139-4826-b2d1-9411b0821283', 'Wrong channel ID for record A'); strictEqual(aRecord.version, 2, 'Should return the new version for record A'); - let bRecord = yield promiseDB.getByScope('https://example.com/b'); + let bRecord = yield db.getByScope('https://example.com/b'); equal(bRecord.channelID, '3c3930ba-44de-40dc-a7ca-8a133ec1a866', 'Wrong channel ID for record B'); strictEqual(bRecord.version, 2, 'Should return the previous version for record B'); - let cRecord = yield promiseDB.getByScope('https://example.com/c'); + let cRecord = yield db.getByScope('https://example.com/c'); equal(cRecord.channelID, 'b63f7bef-0a0d-4236-b41e-086a69dfd316', 'Wrong channel ID for record C'); strictEqual(cRecord.version, 4, diff --git a/dom/push/test/xpcshell/test_notification_incomplete.js b/dom/push/test/xpcshell/test_notification_incomplete.js index 26c11f59a97..b10d8c40231 100644 --- a/dom/push/test/xpcshell/test_notification_incomplete.js +++ b/dom/push/test/xpcshell/test_notification_incomplete.js @@ -19,8 +19,7 @@ function run_test() { add_task(function* test_notification_incomplete() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let records = [{ channelID: '123', pushEndpoint: 'https://example.org/update/1', @@ -43,7 +42,7 @@ add_task(function* test_notification_incomplete() { version: 10 }]; for (let record of records) { - promiseDB.put(record); + db.put(record); } Services.obs.addObserver(function observe(subject, topic, data) { @@ -102,7 +101,7 @@ add_task(function* test_notification_incomplete() { yield waitForPromise(notificationDefer.promise, DEFAULT_TIMEOUT, 'Timed out waiting for incomplete notifications'); - let storeRecords = yield promiseDB.getAllChannelIDs(); + let storeRecords = yield db.getAllChannelIDs(); storeRecords.sort(({pushEndpoint: a}, {pushEndpoint: b}) => compareAscending(a, b)); recordsAreEqual(records, storeRecords); diff --git a/dom/push/test/xpcshell/test_notification_version_string.js b/dom/push/test/xpcshell/test_notification_version_string.js index 345346b5611..79c56ce46aa 100644 --- a/dom/push/test/xpcshell/test_notification_version_string.js +++ b/dom/push/test/xpcshell/test_notification_version_string.js @@ -16,9 +16,8 @@ function run_test() { add_task(function* test_notification_version_string() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); - yield promiseDB.put({ + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); + yield db.put({ channelID: '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b', pushEndpoint: 'https://example.org/updates/1', scope: 'https://example.com/page/1', @@ -66,7 +65,7 @@ add_task(function* test_notification_version_string() { yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, 'Timed out waiting for string acknowledgement'); - let storeRecord = yield promiseDB.getByChannelID( + let storeRecord = yield db.getByChannelID( '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b'); strictEqual(storeRecord.version, 4, 'Wrong record version'); }); diff --git a/dom/push/test/xpcshell/test_register_case.js b/dom/push/test/xpcshell/test_register_case.js index 230c1bf1ced..658f1826a13 100644 --- a/dom/push/test/xpcshell/test_register_case.js +++ b/dom/push/test/xpcshell/test_register_case.js @@ -18,8 +18,7 @@ function run_test() { add_task(function* test_register_case() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); PushService.init({ networkInfo: new MockDesktopNetworkInfo(), @@ -56,7 +55,7 @@ add_task(function* test_register_case() { equal(newRecord.scope, 'https://example.net/case', 'Wrong scope in registration record'); - let record = yield promiseDB.getByChannelID(newRecord.channelID); + let record = yield db.getByChannelID(newRecord.channelID); equal(record.pushEndpoint, 'https://example.com/update/case', 'Wrong push endpoint in database record'); equal(record.scope, 'https://example.net/case', diff --git a/dom/push/test/xpcshell/test_register_flush.js b/dom/push/test/xpcshell/test_register_flush.js index e747958898c..831edefee57 100644 --- a/dom/push/test/xpcshell/test_register_flush.js +++ b/dom/push/test/xpcshell/test_register_flush.js @@ -24,15 +24,14 @@ function run_test() { add_task(function* test_register_flush() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let record = { channelID: '9bcc7efb-86c7-4457-93ea-e24e6eb59b74', pushEndpoint: 'https://example.org/update/1', scope: 'https://example.com/page/1', version: 2 }; - yield promiseDB.put(record); + yield db.put(record); let notifyPromise = promiseObserverNotification('push-notification'); @@ -89,14 +88,14 @@ add_task(function* test_register_flush() { yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, 'Timed out waiting for acknowledgements'); - let prevRecord = yield promiseDB.getByChannelID( + let prevRecord = yield db.getByChannelID( '9bcc7efb-86c7-4457-93ea-e24e6eb59b74'); equal(prevRecord.pushEndpoint, 'https://example.org/update/1', 'Wrong existing push endpoint'); strictEqual(prevRecord.version, 3, 'Should record version updates sent before register responses'); - let registeredRecord = yield promiseDB.getByChannelID(newRecord.channelID); + let registeredRecord = yield db.getByChannelID(newRecord.channelID); equal(registeredRecord.pushEndpoint, 'https://example.org/update/2', 'Wrong new push endpoint'); ok(!registeredRecord.version, 'Should not record premature updates'); diff --git a/dom/push/test/xpcshell/test_register_invalid_channel.js b/dom/push/test/xpcshell/test_register_invalid_channel.js index 1eb0332e2f7..518442a5491 100644 --- a/dom/push/test/xpcshell/test_register_invalid_channel.js +++ b/dom/push/test/xpcshell/test_register_invalid_channel.js @@ -19,8 +19,7 @@ function run_test() { add_task(function* test_register_invalid_channel() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); PushService._generateID = () => channelID; PushService.init({ @@ -55,6 +54,6 @@ add_task(function* test_register_invalid_channel() { 'Wrong error for invalid channel ID' ); - let record = yield promiseDB.getByChannelID(channelID); + let record = yield db.getByChannelID(channelID); ok(!record, 'Should not store records for error responses'); }); diff --git a/dom/push/test/xpcshell/test_register_invalid_endpoint.js b/dom/push/test/xpcshell/test_register_invalid_endpoint.js index cf5e0fa5527..6f2b18683c7 100644 --- a/dom/push/test/xpcshell/test_register_invalid_endpoint.js +++ b/dom/push/test/xpcshell/test_register_invalid_endpoint.js @@ -19,8 +19,7 @@ function run_test() { add_task(function* test_register_invalid_endpoint() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); PushService._generateID = () => channelID; PushService.init({ @@ -57,6 +56,6 @@ add_task(function* test_register_invalid_endpoint() { 'Wrong error for invalid endpoint' ); - let record = yield promiseDB.getByChannelID(channelID); + let record = yield db.getByChannelID(channelID); ok(!record, 'Should not store records with invalid endpoints'); }); diff --git a/dom/push/test/xpcshell/test_register_request_queue.js b/dom/push/test/xpcshell/test_register_request_queue.js index 46e1a97e8c9..7bd9974dd4c 100644 --- a/dom/push/test/xpcshell/test_register_request_queue.js +++ b/dom/push/test/xpcshell/test_register_request_queue.js @@ -19,8 +19,7 @@ function run_test() { add_task(function* test_register_request_queue() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let helloDefer = Promise.defer(); let onHello = after(2, function onHello(request) { diff --git a/dom/push/test/xpcshell/test_register_rollback.js b/dom/push/test/xpcshell/test_register_rollback.js index 077ff2105c9..cf0a7c196b0 100644 --- a/dom/push/test/xpcshell/test_register_rollback.js +++ b/dom/push/test/xpcshell/test_register_rollback.js @@ -23,7 +23,7 @@ function run_test() { add_task(function* test_register_rollback() { let db = new PushDB(); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let handshakes = 0; let registers = 0; @@ -32,8 +32,8 @@ add_task(function* test_register_rollback() { PushService.init({ networkInfo: new MockDesktopNetworkInfo(), db: makeStub(db, { - put(prev, record, successCb, failureCb) { - failureCb('universe has imploded'); + put(prev, record) { + return Promise.reject('universe has imploded'); } }), makeWebSocket(uri) { diff --git a/dom/push/test/xpcshell/test_register_success.js b/dom/push/test/xpcshell/test_register_success.js index 34493051196..eb74fb29d6b 100644 --- a/dom/push/test/xpcshell/test_register_success.js +++ b/dom/push/test/xpcshell/test_register_success.js @@ -23,8 +23,7 @@ function run_test() { add_task(function* test_register_success() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); PushService._generateID = () => channelID; PushService.init({ @@ -66,7 +65,7 @@ add_task(function* test_register_success() { equal(newRecord.scope, 'https://example.org/1', 'Wrong scope in registration record'); - let record = yield promiseDB.getByChannelID(channelID); + let record = yield db.getByChannelID(channelID); equal(record.channelID, channelID, 'Wrong channel ID in database record'); equal(record.pushEndpoint, 'https://example.com/update/1', diff --git a/dom/push/test/xpcshell/test_register_timeout.js b/dom/push/test/xpcshell/test_register_timeout.js index 28017d72753..3e704d85a80 100644 --- a/dom/push/test/xpcshell/test_register_timeout.js +++ b/dom/push/test/xpcshell/test_register_timeout.js @@ -26,8 +26,7 @@ add_task(function* test_register_timeout() { let registers = 0; let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); PushService._generateID = () => channelID; PushService.init({ @@ -90,7 +89,7 @@ add_task(function* test_register_timeout() { 'Wrong error for request timeout' ); - let record = yield promiseDB.getByChannelID(channelID); + let record = yield db.getByChannelID(channelID); ok(!record, 'Should not store records for timed-out responses'); yield waitForPromise( diff --git a/dom/push/test/xpcshell/test_registration_error.js b/dom/push/test/xpcshell/test_registration_error.js index 0e32ab003d8..2daa01f1554 100644 --- a/dom/push/test/xpcshell/test_registration_error.js +++ b/dom/push/test/xpcshell/test_registration_error.js @@ -15,13 +15,13 @@ function run_test() { add_task(function* test_registrations_error() { let db = new PushDB(); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); PushService.init({ networkInfo: new MockDesktopNetworkInfo(), db: makeStub(db, { - getByScope(prev, scope, successCb, failureCb) { - failureCb('oops'); + getByScope(prev, scope) { + return Promise.reject('oops'); } }), makeWebSocket(uri) { diff --git a/dom/push/test/xpcshell/test_registration_success.js b/dom/push/test/xpcshell/test_registration_success.js index 738828c51b8..2373106461d 100644 --- a/dom/push/test/xpcshell/test_registration_success.js +++ b/dom/push/test/xpcshell/test_registration_success.js @@ -15,8 +15,7 @@ function run_test() { add_task(function* test_registration_success() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let records = [{ channelID: 'bf001fe0-2684-42f2-bc4d-a3e14b11dd5b', pushEndpoint: 'https://example.com/update/same-manifest/1', @@ -34,7 +33,7 @@ add_task(function* test_registration_success() { version: 15 }]; for (let record of records) { - yield promiseDB.put(record); + yield db.put(record); } PushService.init({ diff --git a/dom/push/test/xpcshell/test_unregister_error.js b/dom/push/test/xpcshell/test_unregister_error.js index 484b11a9550..d80351a7246 100644 --- a/dom/push/test/xpcshell/test_unregister_error.js +++ b/dom/push/test/xpcshell/test_unregister_error.js @@ -15,9 +15,8 @@ function run_test() { add_task(function* test_unregister_error() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); - yield promiseDB.put({ + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); + yield db.put({ channelID: channelID, pushEndpoint: 'https://example.org/update/failure', scope: 'https://example.net/page/failure', @@ -56,7 +55,7 @@ add_task(function* test_unregister_error() { yield PushNotificationService.unregister( 'https://example.net/page/failure'); - let result = yield promiseDB.getByChannelID(channelID); + let result = yield db.getByChannelID(channelID); ok(!result, 'Deleted push record exists'); // Make sure we send a request to the server. diff --git a/dom/push/test/xpcshell/test_unregister_invalid_json.js b/dom/push/test/xpcshell/test_unregister_invalid_json.js index 81bc1754231..b7d6f79fbf9 100644 --- a/dom/push/test/xpcshell/test_unregister_invalid_json.js +++ b/dom/push/test/xpcshell/test_unregister_invalid_json.js @@ -19,8 +19,7 @@ function run_test() { add_task(function* test_unregister_invalid_json() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); let records = [{ channelID: '87902e90-c57e-4d18-8354-013f4a556559', pushEndpoint: 'https://example.org/update/1', @@ -33,7 +32,7 @@ add_task(function* test_unregister_invalid_json() { version: 1 }]; for (let record of records) { - yield promiseDB.put(record); + yield db.put(record); } let unregisterDefer = Promise.defer(); @@ -62,13 +61,13 @@ add_task(function* test_unregister_invalid_json() { // _sendRequest(). yield PushNotificationService.unregister( 'https://example.edu/page/1'); - let record = yield promiseDB.getByChannelID( + let record = yield db.getByChannelID( '87902e90-c57e-4d18-8354-013f4a556559'); ok(!record, 'Failed to delete unregistered record'); yield PushNotificationService.unregister( 'https://example.net/page/1'); - record = yield promiseDB.getByChannelID( + record = yield db.getByChannelID( '057caa8f-9b99-47ff-891c-adad18ce603e'); ok(!record, 'Failed to delete unregistered record after receiving invalid JSON'); diff --git a/dom/push/test/xpcshell/test_unregister_success.js b/dom/push/test/xpcshell/test_unregister_success.js index 0cf28dc5aab..69ca9ae387c 100644 --- a/dom/push/test/xpcshell/test_unregister_success.js +++ b/dom/push/test/xpcshell/test_unregister_success.js @@ -15,9 +15,8 @@ function run_test() { add_task(function* test_unregister_success() { let db = new PushDB(); - let promiseDB = promisifyDatabase(db); - do_register_cleanup(() => cleanupDatabase(db)); - yield promiseDB.put({ + do_register_cleanup(() => {return db.drop().then(_ => db.close());}); + yield db.put({ channelID, pushEndpoint: 'https://example.org/update/unregister-success', scope: 'https://example.com/page/unregister-success', @@ -52,7 +51,7 @@ add_task(function* test_unregister_success() { yield PushNotificationService.unregister( 'https://example.com/page/unregister-success'); - let record = yield promiseDB.getByChannelID(channelID); + let record = yield db.getByChannelID(channelID); ok(!record, 'Unregister did not remove record'); yield waitForPromise(unregisterDefer.promise, DEFAULT_TIMEOUT, diff --git a/dom/settings/SettingsDB.jsm b/dom/settings/SettingsDB.jsm index e30273352db..492bff72bf4 100644 --- a/dom/settings/SettingsDB.jsm +++ b/dom/settings/SettingsDB.jsm @@ -8,7 +8,7 @@ let Cc = Components.classes; let Ci = Components.interfaces; let Cu = Components.utils; -Cu.importGlobalProperties(['Blob']); +Cu.importGlobalProperties(['Blob', 'File']); Cu.import("resource://gre/modules/Services.jsm"); this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"]; @@ -209,7 +209,7 @@ SettingsDB.prototype = { return "primitive"; } else if (Array.isArray(aObject)) { return "array"; - } else if (aObject instanceof Ci.nsIDOMFile) { + } else if (aObject instanceof File) { return "file"; } else if (aObject instanceof Ci.nsIDOMBlob) { return "blob"; diff --git a/dom/settings/SettingsRequestManager.jsm b/dom/settings/SettingsRequestManager.jsm index 0edac13d65c..92a015fe952 100644 --- a/dom/settings/SettingsRequestManager.jsm +++ b/dom/settings/SettingsRequestManager.jsm @@ -8,6 +8,8 @@ const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; +Cu.importGlobalProperties(['File']); + this.EXPORTED_SYMBOLS = ["SettingsRequestManager"]; Cu.import("resource://gre/modules/SettingsDB.jsm"); @@ -245,7 +247,7 @@ let SettingsRequestManager = { if (!aValue || !aValue.constructor) { return false; } - return (aValue.constructor.name == "Date") || (aValue instanceof Ci.nsIDOMFile) || + return (aValue.constructor.name == "Date") || (aValue instanceof File) || (aValue instanceof Ci.nsIDOMBlob); } // We need to serialize settings objects, otherwise they can change between diff --git a/dom/webidl/File.webidl b/dom/webidl/File.webidl index fe2e83d0996..9a858e41186 100644 --- a/dom/webidl/File.webidl +++ b/dom/webidl/File.webidl @@ -45,6 +45,8 @@ partial interface File { readonly attribute Date lastModifiedDate; [GetterThrows, ChromeOnly] - readonly attribute DOMString mozFullPath; + readonly attribute DOMString path; + [GetterThrows, ChromeOnly] + readonly attribute DOMString mozFullPath; }; diff --git a/dom/webidl/HTMLInputElement.webidl b/dom/webidl/HTMLInputElement.webidl index 31c24fd61c5..f80a4bec0a1 100644 --- a/dom/webidl/HTMLInputElement.webidl +++ b/dom/webidl/HTMLInputElement.webidl @@ -148,7 +148,7 @@ partial interface HTMLInputElement { [GetterThrows] readonly attribute long textLength; - [ChromeOnly] + [Throws, ChromeOnly] sequence mozGetFileNameArray(); [ChromeOnly, Throws] diff --git a/dom/wifi/WifiCertService.cpp b/dom/wifi/WifiCertService.cpp index 1ec5cf3c184..405ee4685dc 100644 --- a/dom/wifi/WifiCertService.cpp +++ b/dom/wifi/WifiCertService.cpp @@ -18,7 +18,7 @@ #include "cert.h" #include "certdb.h" #include "CryptoTask.h" -#include "nsIDOMFile.h" +#include "nsIDOMBlob.h" #include "nsIWifiService.h" #include "nsNetUtil.h" #include "nsServiceManagerUtils.h" diff --git a/gfx/2d/PathHelpers.h b/gfx/2d/PathHelpers.h index 48342736420..d540a7793fd 100644 --- a/gfx/2d/PathHelpers.h +++ b/gfx/2d/PathHelpers.h @@ -192,13 +192,6 @@ struct RectCornerRadii { return radii[aCorner]; } - bool operator==(const RectCornerRadii& aOther) const { - for (size_t i = 0; i < RectCorner::Count; i++) { - if (radii[i] != aOther.radii[i]) return false; - } - return true; - } - void Scale(Float aXScale, Float aYScale) { for (int i = 0; i < RectCorner::Count; i++) { radii[i].Scale(aXScale, aYScale); @@ -361,16 +354,19 @@ inline bool UserToDevicePixelSnapped(Rect& aRect, const DrawTarget& aDrawTarget, * This function has the same behavior as UserToDevicePixelSnapped except that * aRect is not transformed to device space. */ -inline void MaybeSnapToDevicePixels(Rect& aRect, const DrawTarget& aDrawTarget, - bool aIgnoreScale = false) +inline bool MaybeSnapToDevicePixels(Rect& aRect, const DrawTarget& aDrawTarget, + bool aAllowScaleOr90DegreeRotate = false) { - if (UserToDevicePixelSnapped(aRect, aDrawTarget, aIgnoreScale)) { + if (UserToDevicePixelSnapped(aRect, aDrawTarget, + aAllowScaleOr90DegreeRotate)) { // Since UserToDevicePixelSnapped returned true we know there is no // rotation/skew in 'mat', so we can just use TransformBounds() here. Matrix mat = aDrawTarget.GetTransform(); mat.Invert(); aRect = mat.TransformBounds(aRect); + return true; } + return false; } } // namespace gfx diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index f758e765b48..c4b912e66e6 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -712,16 +712,15 @@ SenderHelper::SendTextureSource(GLContext* aGLContext, aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_RECTANGLE, &textureId); } - gfx::IntSize size = aSource->GetSize(); - - // By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding - // texture correctly. textureId is used for tracking in DebugGLTextureData. - RefPtr img = - aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget, - size, - shaderConfig, aFlipY); - if (!IsTextureIdContainsInList(textureId)) { + gfx::IntSize size = aSource->GetSize(); + + // By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding + // texture correctly. textureId is used for tracking in DebugGLTextureData. + RefPtr img = + aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget, + size, + shaderConfig, aFlipY); sTextureIdList.push_back(textureId); WebSocketHelper::GetSocketManager()->AppendDebugData( new DebugGLTextureData(aGLContext, aLayerRef, textureTarget, diff --git a/gfx/thebes/gfxBlur.cpp b/gfx/thebes/gfxBlur.cpp index 33f75bbdd7c..67e6e220157 100644 --- a/gfx/thebes/gfxBlur.cpp +++ b/gfx/thebes/gfxBlur.cpp @@ -14,7 +14,6 @@ #include "mozilla/UniquePtr.h" #include "nsExpirationTracker.h" #include "nsClassHashtable.h" -#include "gfxUtils.h" using namespace mozilla; using namespace mozilla::gfx; @@ -165,56 +164,40 @@ struct BlurCacheKey : public PLDHashEntryHdr { typedef const BlurCacheKey* KeyTypePointer; enum { ALLOW_MEMMOVE = true }; - IntSize mMinSize; + gfxRect mRect; gfxIntSize mBlurRadius; - gfxRGBA mShadowColor; + gfxRect mSkipRect; BackendType mBackend; - RectCornerRadii mCornerRadii; - BlurCacheKey(IntSize aMinimumSize, gfxIntSize aBlurRadius, - RectCornerRadii* aCornerRadii, gfxRGBA aShadowColor, - BackendType aBackend) - : mMinSize(aMinimumSize) + BlurCacheKey(const gfxRect& aRect, const gfxIntSize &aBlurRadius, const gfxRect& aSkipRect, BackendType aBackend) + : mRect(aRect) , mBlurRadius(aBlurRadius) - , mShadowColor(aShadowColor) + , mSkipRect(aSkipRect) , mBackend(aBackend) - , mCornerRadii(aCornerRadii ? *aCornerRadii : RectCornerRadii()) { } explicit BlurCacheKey(const BlurCacheKey* aOther) - : mMinSize(aOther->mMinSize) + : mRect(aOther->mRect) , mBlurRadius(aOther->mBlurRadius) - , mShadowColor(aOther->mShadowColor) + , mSkipRect(aOther->mSkipRect) , mBackend(aOther->mBackend) - , mCornerRadii(aOther->mCornerRadii) { } static PLDHashNumber HashKey(const KeyTypePointer aKey) { - PLDHashNumber hash = 0; - hash = AddToHash(hash, aKey->mMinSize.width, aKey->mMinSize.height); + PLDHashNumber hash = HashBytes(&aKey->mRect.x, 4 * sizeof(gfxFloat)); hash = AddToHash(hash, aKey->mBlurRadius.width, aKey->mBlurRadius.height); - - hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.r, sizeof(gfxFloat))); - hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.g, sizeof(gfxFloat))); - hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.b, sizeof(gfxFloat))); - hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.a, sizeof(gfxFloat))); - - for (int i = 0; i < 4; i++) { - hash = AddToHash(hash, aKey->mCornerRadii[i].width, aKey->mCornerRadii[i].height); - } - + hash = AddToHash(hash, HashBytes(&aKey->mSkipRect.x, 4 * sizeof(gfxFloat))); hash = AddToHash(hash, (uint32_t)aKey->mBackend); return hash; } bool KeyEquals(KeyTypePointer aKey) const { - if (aKey->mMinSize == mMinSize && + if (aKey->mRect.IsEqualInterior(mRect) && aKey->mBlurRadius == mBlurRadius && - aKey->mCornerRadii == mCornerRadii && - aKey->mShadowColor == mShadowColor && + aKey->mSkipRect.IsEqualInterior(mSkipRect) && aKey->mBackend == mBackend) { return true; } @@ -231,15 +214,17 @@ struct BlurCacheKey : public PLDHashEntryHdr { * to the cache entry to be able to be tracked by the nsExpirationTracker. * */ struct BlurCacheData { - BlurCacheData(SourceSurface* aBlur, IntMargin aExtendDestBy, const BlurCacheKey& aKey) + BlurCacheData(SourceSurface* aBlur, const IntPoint& aTopLeft, const gfxRect& aDirtyRect, const BlurCacheKey& aKey) : mBlur(aBlur) - , mExtendDest(aExtendDestBy) + , mTopLeft(aTopLeft) + , mDirtyRect(aDirtyRect) , mKey(aKey) {} BlurCacheData(const BlurCacheData& aOther) : mBlur(aOther.mBlur) - , mExtendDest(aOther.mExtendDest) + , mTopLeft(aOther.mTopLeft) + , mDirtyRect(aOther.mDirtyRect) , mKey(aOther.mKey) { } @@ -249,7 +234,8 @@ struct BlurCacheData { nsExpirationState mExpirationState; RefPtr mBlur; - IntMargin mExtendDest; + IntPoint mTopLeft; + gfxRect mDirtyRect; BlurCacheKey mKey; }; @@ -273,18 +259,19 @@ class BlurCache final : public nsExpirationTracker mHashEntries.Remove(aObject->mKey); } - BlurCacheData* Lookup(const IntSize aMinSize, + BlurCacheData* Lookup(const gfxRect& aRect, const gfxIntSize& aBlurRadius, - RectCornerRadii* aCornerRadii, - const gfxRGBA& aShadowColor, - BackendType aBackendType) + const gfxRect& aSkipRect, + BackendType aBackendType, + const gfxRect* aDirtyRect) { BlurCacheData* blur = - mHashEntries.Get(BlurCacheKey(aMinSize, aBlurRadius, - aCornerRadii, aShadowColor, - aBackendType)); + mHashEntries.Get(BlurCacheKey(aRect, aBlurRadius, aSkipRect, aBackendType)); if (blur) { + if (aDirtyRect && !blur->mDirtyRect.Contains(*aDirtyRect)) { + return nullptr; + } MarkUsed(blur); } @@ -319,163 +306,52 @@ class BlurCache final : public nsExpirationTracker static BlurCache* gBlurCache = nullptr; -static IntSize -ComputeMinSizeForShadowShape(RectCornerRadii* aCornerRadii, - gfxIntSize aBlurRadius, - IntMargin& aSlice, - const IntSize& aRectSize) -{ - float cornerWidth = 0; - float cornerHeight = 0; - if (aCornerRadii) { - RectCornerRadii corners = *aCornerRadii; - for (size_t i = 0; i < 4; i++) { - cornerWidth = std::max(cornerWidth, corners[i].width); - cornerHeight = std::max(cornerHeight, corners[i].height); - } - } - - aSlice = IntMargin(ceil(cornerHeight) + aBlurRadius.height, - ceil(cornerWidth) + aBlurRadius.width, - ceil(cornerHeight) + aBlurRadius.height, - ceil(cornerWidth) + aBlurRadius.width); - - // Include 1 pixel for the stretchable strip in the middle. - IntSize minSize(aSlice.LeftRight() + 1, - aSlice.TopBottom() + 1); - - // If aRectSize is smaller than minSize, the border-image approach won't - // work; there's no way to squeeze parts of the min box-shadow source - // image such that the result looks correct. So we need to adjust minSize - // in such a way that we can later draw it without stretching in the affected - // dimension. We also need to adjust "slice" to ensure that we're not trying - // to slice away more than we have. - if (aRectSize.width < minSize.width) { - minSize.width = aRectSize.width; - aSlice.left = 0; - aSlice.right = 0; - } - if (aRectSize.height < minSize.height) { - minSize.height = aRectSize.height; - aSlice.top = 0; - aSlice.bottom = 0; - } - - MOZ_ASSERT(aSlice.LeftRight() <= minSize.width); - MOZ_ASSERT(aSlice.TopBottom() <= minSize.height); - return minSize; -} - -void -CacheBlur(DrawTarget& aDT, - const IntSize& aMinSize, - const gfxIntSize& aBlurRadius, - RectCornerRadii* aCornerRadii, - const gfxRGBA& aShadowColor, - IntMargin aExtendDest, - SourceSurface* aBoxShadow) -{ - BlurCacheKey key(aMinSize, aBlurRadius, aCornerRadii, aShadowColor, aDT.GetBackendType()); - BlurCacheData* data = new BlurCacheData(aBoxShadow, aExtendDest, key); - if (!gBlurCache->RegisterEntry(data)) { - delete data; - } -} - -// Blurs a small surface and creates the mask. -static TemporaryRef -CreateBlurMask(const IntSize& aRectSize, - RectCornerRadii* aCornerRadii, - gfxIntSize aBlurRadius, - IntMargin& aExtendDestBy, - IntMargin& aSliceBorder, - DrawTarget& aDestDrawTarget) -{ - IntMargin slice; - IntSize minSize = - ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, slice, aRectSize); - IntRect minRect(IntPoint(), minSize); - - gfxAlphaBoxBlur blur; - gfxContext* blurCtx = blur.Init(ThebesRect(Rect(minRect)), gfxIntSize(), - aBlurRadius, nullptr, nullptr); - if (!blurCtx) { - return nullptr; - } - - DrawTarget* blurDT = blurCtx->GetDrawTarget(); - ColorPattern black(Color(0.f, 0.f, 0.f, 1.f)); - - if (aCornerRadii) { - RefPtr roundedRect = - MakePathForRoundedRect(*blurDT, Rect(minRect), *aCornerRadii); - blurDT->Fill(roundedRect, black); - } else { - blurDT->FillRect(Rect(minRect), black); - } - - IntPoint topLeft; - RefPtr result = blur.DoBlur(&aDestDrawTarget, &topLeft); - - IntRect expandedMinRect(topLeft, result->GetSize()); - aExtendDestBy = expandedMinRect - minRect; - aSliceBorder = slice + aExtendDestBy; - - MOZ_ASSERT(aSliceBorder.LeftRight() <= expandedMinRect.width); - MOZ_ASSERT(aSliceBorder.TopBottom() <= expandedMinRect.height); - - return result.forget(); -} - -static TemporaryRef -CreateBoxShadow(SourceSurface* aBlurMask, const gfxRGBA& aShadowColor) -{ - IntSize blurredSize = aBlurMask->GetSize(); - gfxPlatform* platform = gfxPlatform::GetPlatform(); - RefPtr boxShadowDT = - platform->CreateOffscreenContentDrawTarget(blurredSize, SurfaceFormat::B8G8R8A8); - - ColorPattern shadowColor(ToDeviceColor(aShadowColor)); - boxShadowDT->MaskSurface(shadowColor, aBlurMask, Point(0, 0)); - return boxShadowDT->Snapshot(); -} - SourceSurface* -GetBlur(DrawTarget& aDT, - const IntSize& aRectSize, +GetCachedBlur(DrawTarget *aDT, + const gfxRect& aRect, const gfxIntSize& aBlurRadius, - RectCornerRadii* aCornerRadii, - const gfxRGBA& aShadowColor, - IntMargin& aExtendDestBy, - IntMargin& aSlice) + const gfxRect& aSkipRect, + const gfxRect& aDirtyRect, + IntPoint* aTopLeft) { if (!gBlurCache) { gBlurCache = new BlurCache(); } - - IntSize minSize = - ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, aSlice, aRectSize); - - BlurCacheData* cached = gBlurCache->Lookup(minSize, aBlurRadius, - aCornerRadii, aShadowColor, - aDT.GetBackendType()); + BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect, + aDT->GetBackendType(), + &aDirtyRect); if (cached) { - // See CreateBlurMask() for these values - aExtendDestBy = cached->mExtendDest; - aSlice = aSlice + aExtendDestBy; + *aTopLeft = cached->mTopLeft; return cached->mBlur; } + return nullptr; +} - RefPtr blurMask = - CreateBlurMask(aRectSize, aCornerRadii, aBlurRadius, aExtendDestBy, aSlice, aDT); - - if (!blurMask) { - return nullptr; +void +CacheBlur(DrawTarget *aDT, + const gfxRect& aRect, + const gfxIntSize& aBlurRadius, + const gfxRect& aSkipRect, + SourceSurface* aBlur, + const IntPoint& aTopLeft, + const gfxRect& aDirtyRect) +{ + // If we already had a cached value with this key, but an incorrect dirty region then just update + // the existing entry + if (BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect, + aDT->GetBackendType(), + nullptr)) { + cached->mBlur = aBlur; + cached->mTopLeft = aTopLeft; + cached->mDirtyRect = aDirtyRect; + return; } - RefPtr boxShadow = CreateBoxShadow(blurMask, aShadowColor); - CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow); - return boxShadow; + BlurCacheKey key(aRect, aBlurRadius, aSkipRect, aDT->GetBackendType()); + BlurCacheData* data = new BlurCacheData(aBlur, aTopLeft, aDirtyRect, key); + if (!gBlurCache->RegisterEntry(data)) { + delete data; + } } void @@ -485,45 +361,8 @@ gfxAlphaBoxBlur::ShutdownBlurCache() gBlurCache = nullptr; } -static Rect -RectWithEdgesTRBL(Float aTop, Float aRight, Float aBottom, Float aLeft) -{ - return Rect(aLeft, aTop, aRight - aLeft, aBottom - aTop); -} - -static void -RepeatOrStretchSurface(DrawTarget& aDT, SourceSurface* aSurface, - const Rect& aDest, const Rect& aSrc) -{ - if (!aDT.GetTransform().IsRectilinear() && - aDT.GetBackendType() != BackendType::CAIRO) { - // Use stretching if possible, since it leads to less seams when the - // destination is transformed. However, don't do this if we're using cairo, - // because if cairo is using pixman it won't render anything for large - // stretch factors because pixman's internal fixed point precision is not - // high enough to handle those scale factors. - aDT.DrawSurface(aSurface, aDest, aSrc); - return; - } - - SurfacePattern pattern(aSurface, ExtendMode::REPEAT, - Matrix::Translation(aDest.TopLeft() - aSrc.TopLeft()), - Filter::GOOD, RoundedToInt(aSrc)); - aDT.FillRect(aDest, pattern); -} - -/*** - * We draw a blurred a rectangle by only blurring a smaller rectangle and - * splitting the rectangle into 9 parts. - * First, a small minimum source rect is calculated and used to create a blur - * mask since the actual blurring itself is expensive. Next, we use the mask - * with the given shadow color to create a minimally-sized box shadow of the - * right color. Finally, we cut out the 9 parts from the box-shadow source and - * paint each part in the right place, stretching the non-corner parts to fill - * the space between the corners. - */ /* static */ void -gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx, +gfxAlphaBoxBlur::BlurRectangle(gfxContext *aDestinationCtx, const gfxRect& aRect, RectCornerRadii* aCornerRadii, const gfxPoint& aBlurStdDev, @@ -531,103 +370,43 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx, const gfxRect& aDirtyRect, const gfxRect& aSkipRect) { - DrawTarget& destDrawTarget = *aDestinationCtx->GetDrawTarget(); + DrawTarget& aDrawTarget = *aDestinationCtx->GetDrawTarget(); + gfxIntSize blurRadius = CalculateBlurRadius(aBlurStdDev); - IntRect rect = RoundedToInt(ToRect(aRect)); - IntMargin extendDestBy; - IntMargin slice; + IntPoint topLeft; + RefPtr surface = GetCachedBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, aDirtyRect, &topLeft); + if (!surface) { + // Create the temporary surface for blurring + gfxAlphaBoxBlur blur; + gfxContext* blurCtx = blur.Init(aRect, gfxIntSize(), blurRadius, &aDirtyRect, &aSkipRect); + if (!blurCtx) { + return; + } + DrawTarget* blurDT = blurCtx->GetDrawTarget(); - RefPtr boxShadow = GetBlur(destDrawTarget, - rect.Size(), blurRadius, - aCornerRadii, aShadowColor, - extendDestBy, slice); - if (!boxShadow) { - return; + Rect shadowGfxRect = ToRect(aRect); + shadowGfxRect.Round(); + + ColorPattern black(Color(0.f, 0.f, 0.f, 1.f)); // For masking, so no ToDeviceColor! + if (aCornerRadii) { + RefPtr roundedRect = MakePathForRoundedRect(*blurDT, + shadowGfxRect, + *aCornerRadii); + blurDT->Fill(roundedRect, black); + } else { + blurDT->FillRect(shadowGfxRect, black); + } + + surface = blur.DoBlur(&aDrawTarget, &topLeft); + if (!surface) { + return; + } + CacheBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, surface, topLeft, aDirtyRect); } - destDrawTarget.PushClipRect(ToRect(aDirtyRect)); - - // Copy the right parts from boxShadow into destDrawTarget. The middle parts - // will be stretched, border-image style. - - Rect srcOuter(Point(), Size(boxShadow->GetSize())); - Rect srcInner = srcOuter; - srcInner.Deflate(Margin(slice)); - - rect.Inflate(extendDestBy); - Rect dstOuter(rect); - Rect dstInner(rect); - dstInner.Deflate(Margin(slice)); - - // Corners: top left, top right, bottom left, bottom right - destDrawTarget.DrawSurface(boxShadow, - RectWithEdgesTRBL(dstOuter.Y(), dstInner.X(), - dstInner.Y(), dstOuter.X()), - RectWithEdgesTRBL(srcOuter.Y(), srcInner.X(), - srcInner.Y(), srcOuter.X())); - destDrawTarget.DrawSurface(boxShadow, - RectWithEdgesTRBL(dstOuter.Y(), dstOuter.XMost(), - dstInner.Y(), dstInner.XMost()), - RectWithEdgesTRBL(srcOuter.Y(), srcOuter.XMost(), - srcInner.Y(), srcInner.XMost())); - destDrawTarget.DrawSurface(boxShadow, - RectWithEdgesTRBL(dstInner.YMost(), dstInner.X(), - dstOuter.YMost(), dstOuter.X()), - RectWithEdgesTRBL(srcInner.YMost(), srcInner.X(), - srcOuter.YMost(), srcOuter.X())); - destDrawTarget.DrawSurface(boxShadow, - RectWithEdgesTRBL(dstInner.YMost(), dstOuter.XMost(), - dstOuter.YMost(), dstInner.XMost()), - RectWithEdgesTRBL(srcInner.YMost(), srcOuter.XMost(), - srcOuter.YMost(), srcInner.XMost())); - - // Edges: top, left, right, bottom - RepeatOrStretchSurface(destDrawTarget, boxShadow, - RectWithEdgesTRBL(dstOuter.Y(), dstInner.XMost(), - dstInner.Y(), dstInner.X()), - RectWithEdgesTRBL(srcOuter.Y(), srcInner.XMost(), - srcInner.Y(), srcInner.X())); - RepeatOrStretchSurface(destDrawTarget, boxShadow, - RectWithEdgesTRBL(dstInner.Y(), dstInner.X(), - dstInner.YMost(), dstOuter.X()), - RectWithEdgesTRBL(srcInner.Y(), srcInner.X(), - srcInner.YMost(), srcOuter.X())); - RepeatOrStretchSurface(destDrawTarget, boxShadow, - RectWithEdgesTRBL(dstInner.Y(), dstOuter.XMost(), - dstInner.YMost(), dstInner.XMost()), - RectWithEdgesTRBL(srcInner.Y(), srcOuter.XMost(), - srcInner.YMost(), srcInner.XMost())); - RepeatOrStretchSurface(destDrawTarget, boxShadow, - RectWithEdgesTRBL(dstInner.YMost(), dstInner.XMost(), - dstOuter.YMost(), dstInner.X()), - RectWithEdgesTRBL(srcInner.YMost(), srcInner.XMost(), - srcOuter.YMost(), srcInner.X())); - - // Middle part - RepeatOrStretchSurface(destDrawTarget, boxShadow, - RectWithEdgesTRBL(dstInner.Y(), dstInner.XMost(), - dstInner.YMost(), dstInner.X()), - RectWithEdgesTRBL(srcInner.Y(), srcInner.XMost(), - srcInner.YMost(), srcInner.X())); - - // A note about anti-aliasing and seems between adjacent parts: - // We don't explicitly disable anti-aliasing in the DrawSurface calls above, - // so if there's a transform on destDrawTarget that is not pixel-aligned, - // there will be seams between adjacent parts of the box-shadow. It's hard to - // avoid those without the use of an intermediate surface. - // You might think that we could avoid those by just turning of AA, but there - // is a problem with that: Box-shadow rendering needs to clip out the - // element's border box, and we'd like that clip to have anti-aliasing - - // especially if the element has rounded corners! So we can't do that unless - // we have a way to say "Please anti-alias the clip, but don't antialias the - // destination rect of the DrawSurface call". - // On OS X there is an additional problem with turning off AA: CoreGraphics - // will not just fill the pixels that have their pixel center inside the - // filled shape. Instead, it will fill all the pixels which are partially - // covered by the shape. So for pixels on the edge between two adjacent parts, - // all those pixels will be painted to by both parts, which looks very bad. - - destDrawTarget.PopClip(); + aDestinationCtx->SetColor(aShadowColor); + Rect dirtyRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); + DrawBlur(aDestinationCtx, surface, topLeft, &dirtyRect); } diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp index f98e2100696..6ba3b592f6b 100644 --- a/gfx/thebes/gfxGDIFont.cpp +++ b/gfx/thebes/gfxGDIFont.cpp @@ -304,6 +304,39 @@ gfxGDIFont::Initialize() mMetrics->maxAdvance = mMetrics->aveCharWidth; } + // For fonts with USE_TYPO_METRICS set in the fsSelection field, + // let the OS/2 sTypo* metrics override the previous values. + // (see http://www.microsoft.com/typography/otspec/os2.htm#fss) + // Using the equivalent values from oMetrics provides inconsistent + // results with CFF fonts, so we instead rely on OS2Table. + gfxFontEntry::AutoTable os2Table(mFontEntry, + TRUETYPE_TAG('O','S','/','2')); + if (os2Table) { + uint32_t len; + const OS2Table *os2 = + reinterpret_cast(hb_blob_get_data(os2Table, + &len)); + if (len >= offsetof(OS2Table, sTypoLineGap) + sizeof(int16_t)) { + const uint16_t kUseTypoMetricsMask = 1 << 7; + if ((uint16_t(os2->fsSelection) & kUseTypoMetricsMask)) { + double ascent = int16_t(os2->sTypoAscender); + double descent = int16_t(os2->sTypoDescender); + double lineGap = int16_t(os2->sTypoLineGap); + mMetrics->maxAscent = ROUND(ascent * mFUnitsConvFactor); + mMetrics->maxDescent = -ROUND(descent * mFUnitsConvFactor); + mMetrics->maxHeight = + mMetrics->maxAscent + mMetrics->maxDescent; + mMetrics->internalLeading = + mMetrics->maxHeight - mMetrics->emHeight; + gfxFloat lineHeight = + ROUND((ascent - descent + lineGap) * mFUnitsConvFactor); + lineHeight = std::max(lineHeight, mMetrics->maxHeight); + mMetrics->externalLeading = + lineHeight - mMetrics->maxHeight; + } + } + } + // Cache the width of a single space. SIZE size; GetTextExtentPoint32W(dc.GetDC(), L" ", 1, &size); diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index abdb821f23a..832cc5f22f8 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -69,47 +69,49 @@ class GlobalObject : public NativeObject */ static const unsigned STANDARD_CLASS_SLOTS = JSProto_LIMIT * 3; - /* Various function values needed by the engine. */ - static const unsigned EVAL = APPLICATION_SLOTS + STANDARD_CLASS_SLOTS; - static const unsigned CREATE_DATAVIEW_FOR_THIS = EVAL + 1; - static const unsigned THROWTYPEERROR = CREATE_DATAVIEW_FOR_THIS + 1; + enum : unsigned { + /* Various function values needed by the engine. */ + EVAL = APPLICATION_SLOTS + STANDARD_CLASS_SLOTS, + CREATE_DATAVIEW_FOR_THIS, + THROWTYPEERROR, - /* - * Instances of the internal createArrayFromBuffer function used by the - * typed array code, one per typed array element type. - */ - static const unsigned FROM_BUFFER_UINT8 = THROWTYPEERROR + 1; - static const unsigned FROM_BUFFER_INT8 = FROM_BUFFER_UINT8 + 1; - static const unsigned FROM_BUFFER_UINT16 = FROM_BUFFER_INT8 + 1; - static const unsigned FROM_BUFFER_INT16 = FROM_BUFFER_UINT16 + 1; - static const unsigned FROM_BUFFER_UINT32 = FROM_BUFFER_INT16 + 1; - static const unsigned FROM_BUFFER_INT32 = FROM_BUFFER_UINT32 + 1; - static const unsigned FROM_BUFFER_FLOAT32 = FROM_BUFFER_INT32 + 1; - static const unsigned FROM_BUFFER_FLOAT64 = FROM_BUFFER_FLOAT32 + 1; - static const unsigned FROM_BUFFER_UINT8CLAMPED = FROM_BUFFER_FLOAT64 + 1; + /* + * Instances of the internal createArrayFromBuffer function used by the + * typed array code, one per typed array element type. + */ + FROM_BUFFER_UINT8, + FROM_BUFFER_INT8, + FROM_BUFFER_UINT16, + FROM_BUFFER_INT16, + FROM_BUFFER_UINT32, + FROM_BUFFER_INT32, + FROM_BUFFER_FLOAT32, + FROM_BUFFER_FLOAT64, + FROM_BUFFER_UINT8CLAMPED, - /* One-off properties stored after slots for built-ins. */ - static const unsigned ARRAY_ITERATOR_PROTO = FROM_BUFFER_UINT8CLAMPED + 1; - static const unsigned STRING_ITERATOR_PROTO = ARRAY_ITERATOR_PROTO + 1; - static const unsigned LEGACY_GENERATOR_OBJECT_PROTO = STRING_ITERATOR_PROTO + 1; - static const unsigned STAR_GENERATOR_OBJECT_PROTO = LEGACY_GENERATOR_OBJECT_PROTO + 1; - static const unsigned MAP_ITERATOR_PROTO = STAR_GENERATOR_OBJECT_PROTO + 1; - static const unsigned SET_ITERATOR_PROTO = MAP_ITERATOR_PROTO + 1; - static const unsigned COLLATOR_PROTO = SET_ITERATOR_PROTO + 1; - static const unsigned NUMBER_FORMAT_PROTO = COLLATOR_PROTO + 1; - static const unsigned DATE_TIME_FORMAT_PROTO = NUMBER_FORMAT_PROTO + 1; - static const unsigned REGEXP_STATICS = DATE_TIME_FORMAT_PROTO + 1; - static const unsigned WARNED_ONCE_FLAGS = REGEXP_STATICS + 1; - static const unsigned RUNTIME_CODEGEN_ENABLED = WARNED_ONCE_FLAGS + 1; - static const unsigned DEBUGGERS = RUNTIME_CODEGEN_ENABLED + 1; - static const unsigned INTRINSICS = DEBUGGERS + 1; - static const unsigned FLOAT32X4_TYPE_DESCR = INTRINSICS + 1; - static const unsigned FLOAT64X2_TYPE_DESCR = FLOAT32X4_TYPE_DESCR + 1; - static const unsigned INT32X4_TYPE_DESCR = FLOAT64X2_TYPE_DESCR + 1; - static const unsigned FOR_OF_PIC_CHAIN = INT32X4_TYPE_DESCR + 1; + /* One-off properties stored after slots for built-ins. */ + ARRAY_ITERATOR_PROTO, + STRING_ITERATOR_PROTO, + LEGACY_GENERATOR_OBJECT_PROTO, + STAR_GENERATOR_OBJECT_PROTO, + MAP_ITERATOR_PROTO, + SET_ITERATOR_PROTO, + COLLATOR_PROTO, + NUMBER_FORMAT_PROTO, + DATE_TIME_FORMAT_PROTO, + REGEXP_STATICS, + WARNED_ONCE_FLAGS, + RUNTIME_CODEGEN_ENABLED, + DEBUGGERS, + INTRINSICS, + FLOAT32X4_TYPE_DESCR, + FLOAT64X2_TYPE_DESCR, + INT32X4_TYPE_DESCR, + FOR_OF_PIC_CHAIN, - /* Total reserved-slot count for global objects. */ - static const unsigned RESERVED_SLOTS = FOR_OF_PIC_CHAIN + 1; + /* Total reserved-slot count for global objects. */ + RESERVED_SLOTS + }; /* * The slot count must be in the public API for JSCLASS_GLOBAL_FLAGS, and diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 298b7e89069..659cd7c102f 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -28,7 +28,6 @@ #include "mozilla/dom/StructuredCloneTags.h" #include "mozilla/dom/WindowBinding.h" #include "nsZipArchive.h" -#include "nsIDOMFile.h" #include "nsIDOMFileList.h" #include "nsWindowMemoryReporter.h" #include "nsDOMClassInfo.h" diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 5dc8105bbe0..9f6fbc4cbb6 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -3394,8 +3394,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) // 1MB is the default stack size on Windows, so use 900k. // Windows PGO stack frames have unfortunately gotten pretty large lately. :-( const size_t kStackQuota = 900 * 1024; - const size_t kTrustedScriptBuffer = (sizeof(size_t) == 8) ? 160 * 1024 - : 100 * 1024; + const size_t kTrustedScriptBuffer = (sizeof(size_t) == 8) ? 180 * 1024 //win64 + : 120 * 1024; //win32 // The following two configurations are linux-only. Given the numbers above, // we use 50k and 100k trusted buffers on 32-bit and 64-bit respectively. #elif defined(DEBUG) diff --git a/js/xpconnect/tests/chrome/test_cloneInto.xul b/js/xpconnect/tests/chrome/test_cloneInto.xul index e5f58783b50..db4c61b0f3a 100644 --- a/js/xpconnect/tests/chrome/test_cloneInto.xul +++ b/js/xpconnect/tests/chrome/test_cloneInto.xul @@ -49,7 +49,7 @@ if (Array.isArray(a)) return 'array'; - if (a instanceof Ci.nsIDOMFile) + if (a instanceof File) return 'file'; if (a instanceof Ci.nsIDOMBlob) diff --git a/js/xpconnect/tests/unit/component-blob.js b/js/xpconnect/tests/unit/component-blob.js index fd528c86be7..7c50f7c925d 100644 --- a/js/xpconnect/tests/unit/component-blob.js +++ b/js/xpconnect/tests/unit/component-blob.js @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.importGlobalProperties(['Blob']); +Components.utils.importGlobalProperties(['Blob', 'File']); const Cc = Components.classes; const Ci = Components.interfaces; @@ -31,7 +31,7 @@ BlobComponent.prototype = // do some tests do_check_true(f1 instanceof Ci.nsIDOMBlob, "Should be a DOM Blob"); - do_check_true(!(f1 instanceof Ci.nsIDOMFile), "Should not be a DOM File"); + do_check_true(!(f1 instanceof File), "Should not be a DOM File"); do_check_true(f1.type == "text/xml", "Wrong type"); diff --git a/js/xpconnect/tests/unit/component-file.js b/js/xpconnect/tests/unit/component-file.js index 6a1b6ac8d77..d9c51d9f3fe 100644 --- a/js/xpconnect/tests/unit/component-file.js +++ b/js/xpconnect/tests/unit/component-file.js @@ -36,8 +36,8 @@ FileComponent.prototype = var f2 = new File(file); // do some tests - do_check_true(f1 instanceof Ci.nsIDOMFile, "Should be a DOM File"); - do_check_true(f2 instanceof Ci.nsIDOMFile, "Should be a DOM File"); + do_check_true(f1 instanceof File, "Should be a DOM File"); + do_check_true(f2 instanceof File, "Should be a DOM File"); do_check_true(f1.name == "xpcshell.ini", "Should be the right file"); do_check_true(f2.name == "xpcshell.ini", "Should be the right file"); diff --git a/js/xpconnect/tests/unit/test_blob2.js b/js/xpconnect/tests/unit/test_blob2.js index 2d39532f4dd..e031d0813c8 100644 --- a/js/xpconnect/tests/unit/test_blob2.js +++ b/js/xpconnect/tests/unit/test_blob2.js @@ -2,7 +2,7 @@ * 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/. */ -Components.utils.importGlobalProperties(['Blob']); +Components.utils.importGlobalProperties(['Blob', 'File']); const Ci = Components.interfaces; @@ -15,7 +15,7 @@ function run_test() { // do some tests do_check_true(f1 instanceof Ci.nsIDOMBlob, "Should be a DOM Blob"); - do_check_true(!(f1 instanceof Ci.nsIDOMFile), "Should not be a DOM File"); + do_check_true(!(f1 instanceof File), "Should not be a DOM File"); do_check_true(f1.type == "text/xml", "Wrong type"); diff --git a/js/xpconnect/tests/unit/test_file2.js b/js/xpconnect/tests/unit/test_file2.js index 7e52f8be853..375ba248854 100644 --- a/js/xpconnect/tests/unit/test_file2.js +++ b/js/xpconnect/tests/unit/test_file2.js @@ -21,8 +21,8 @@ function run_test() { var f2 = new File(file); // do some tests - do_check_true(f1 instanceof Ci.nsIDOMFile, "Should be a DOM File"); - do_check_true(f2 instanceof Ci.nsIDOMFile, "Should be a DOM File"); + do_check_true(f1 instanceof File, "Should be a DOM File"); + do_check_true(f2 instanceof File, "Should be a DOM File"); do_check_true(f1.name == "xpcshell.ini", "Should be the right file"); do_check_true(f2.name == "xpcshell.ini", "Should be the right file"); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 930e6992ffe..1c8555a5861 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1478,7 +1478,7 @@ void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder, nsIntRect pxRect = mVisibleRect.ToOutsidePixels(mFrame->PresContext()->AppUnitsPerDevPixel()); Rect rect(pxRect.x, pxRect.y, pxRect.width, pxRect.height); - MaybeSnapToDevicePixels(rect, aDrawTarget); + MaybeSnapToDevicePixels(rect, aDrawTarget, true); aDrawTarget.FillRect(rect, color); } diff --git a/layout/reftests/bugs/1155828-1-ref.html b/layout/reftests/bugs/1155828-1-ref.html deleted file mode 100644 index b5c8b5e0829..00000000000 --- a/layout/reftests/bugs/1155828-1-ref.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - -
- - diff --git a/layout/reftests/bugs/1155828-1.html b/layout/reftests/bugs/1155828-1.html deleted file mode 100644 index e6ea76d9e5e..00000000000 --- a/layout/reftests/bugs/1155828-1.html +++ /dev/null @@ -1,26 +0,0 @@ - - - -Scrolling shouldn't cause gaps in the shadow - - -
- - diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 87cd9d9ed9c..403a2858ca1 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1923,5 +1923,4 @@ skip-if(!asyncPanZoom) fuzzy-if(B2G,101,887) == 1133905-6-vh-rtl.html 1133905-re skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul == 1151145-1.html 1151145-1-ref.html == 1151306-1.html 1151306-1-ref.html -== 1155828-1.html 1155828-1-ref.html == 1156129-1.html 1156129-1-ref.html diff --git a/layout/reftests/fonts/mark-generate.py b/layout/reftests/fonts/mark-generate.py index f831f4c4a15..8d537fa813f 100755 --- a/layout/reftests/fonts/mark-generate.py +++ b/layout/reftests/fonts/mark-generate.py @@ -110,3 +110,44 @@ f.os2_typolinegap = lineheight - (f.os2_typoascent - f.os2_typodescent) f.hhea_linegap = lineheight - 800 f.generate("markA-lineheight" + str(lineheight) + ".ttf") + +# Fonts with known winHeight and typoLineHeight such that winHeight is much +# larger than typoLineHeight. +f = fontforge.font() +typoLineHeight = 2700 +winHeight = 6000 +n = "MarkA-lineheight" + str(winHeight) +n = n + "-typolineheight" + str(typoLineHeight) +f.fontname = n +f.familyname = n +f.fullname = n +f.copyright = "Copyright (c) 2008-2015 Mozilla Corporation" + +g = f.createChar(ord(" "), "space") +g.width = 1000 +g = f.createChar(ord("A"), "A") +g.importOutlines("mark-glyph.svg") +g.width = 1500 + +f.os2_typoascent_add = False +f.os2_typoascent = 800 +f.os2_typodescent_add = False +f.os2_typodescent = -200 +f.os2_typolinegap = typoLineHeight - (f.os2_typoascent - f.os2_typodescent) + +f.hhea_ascent = winHeight / 2 +f.hhea_ascent_add = False +f.hhea_descent = winHeight / 2 +f.hhea_descent_add = False +f.hhea_linegap = 0 + +f.os2_winascent = winHeight / 2 +f.os2_winascent_add = False +f.os2_windescent = winHeight / 2 +f.os2_windescent_add = False + +f.os2_use_typo_metrics = True +f.generate("markA-lineheight" + str(winHeight) + + "-typolineheight" + str(typoLineHeight) + ".otf") +f.generate("markA-lineheight" + str(winHeight) + + "-typolineheight" + str(typoLineHeight) + ".ttf") diff --git a/layout/reftests/fonts/markA-lineheight6000-typolineheight2700.otf b/layout/reftests/fonts/markA-lineheight6000-typolineheight2700.otf new file mode 100644 index 00000000000..13b7b3e917d Binary files /dev/null and b/layout/reftests/fonts/markA-lineheight6000-typolineheight2700.otf differ diff --git a/layout/reftests/fonts/markA-lineheight6000-typolineheight2700.ttf b/layout/reftests/fonts/markA-lineheight6000-typolineheight2700.ttf new file mode 100644 index 00000000000..0f84bb8b8c3 Binary files /dev/null and b/layout/reftests/fonts/markA-lineheight6000-typolineheight2700.ttf differ diff --git a/layout/reftests/text/lineheight-metrics-2-ref.html b/layout/reftests/text/lineheight-metrics-2-ref.html new file mode 100644 index 00000000000..ecf9fbf1ca9 --- /dev/null +++ b/layout/reftests/text/lineheight-metrics-2-ref.html @@ -0,0 +1,17 @@ +Testcase, bug 947650 and 598900 + + +
+ diff --git a/layout/reftests/text/lineheight-metrics-2a.html b/layout/reftests/text/lineheight-metrics-2a.html new file mode 100644 index 00000000000..1d4e00129ce --- /dev/null +++ b/layout/reftests/text/lineheight-metrics-2a.html @@ -0,0 +1,29 @@ +Testcase, bug 947650 and 598900 + + +
A
+ diff --git a/layout/reftests/text/lineheight-metrics-2b.html b/layout/reftests/text/lineheight-metrics-2b.html new file mode 100644 index 00000000000..48592118233 --- /dev/null +++ b/layout/reftests/text/lineheight-metrics-2b.html @@ -0,0 +1,29 @@ +Testcase, bug 947650 and 598900 + + +
A
+ diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 3ce62e7541c..0c2a970fe75 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -24,7 +24,9 @@ HTTP(..) load ligature-with-space-1.html == line-editing-1c.html line-editing-1-ref.html == line-editing-1d.html line-editing-1-ref.html == line-editing-1e.html line-editing-1-ref.html -fails-if(cocoaWidget||winWidget) HTTP(..) == lineheight-metrics-1.html lineheight-metrics-1-ref.html # bug 657864 +fails-if(cocoaWidget||(winWidget&&!layersGPUAccelerated)) HTTP(..) == lineheight-metrics-1.html lineheight-metrics-1-ref.html # bug 657864 +HTTP(..) == lineheight-metrics-2a.html lineheight-metrics-2-ref.html +HTTP(..) == lineheight-metrics-2b.html lineheight-metrics-2-ref.html == lineheight-percentage-1.html lineheight-percentage-1-ref.html skip-if(B2G||Mulet) == long-1.html long-ref.html # Initial mulet triage: parity with B2G/B2G Desktop fuzzy-if(Android,255,42) == pre-line-1.html pre-line-1-ref.html diff --git a/media/webrtc/signaling/src/common/PtrVector.h b/media/webrtc/signaling/src/common/PtrVector.h index ebcada850ac..68c76047282 100644 --- a/media/webrtc/signaling/src/common/PtrVector.h +++ b/media/webrtc/signaling/src/common/PtrVector.h @@ -5,6 +5,7 @@ #ifndef PtrVector_h #define PtrVector_h +#include #include namespace mozilla @@ -16,6 +17,18 @@ namespace mozilla template class PtrVector { public: + PtrVector() = default; + PtrVector(const PtrVector&) = delete; + PtrVector(PtrVector&& aOther) + : values(Move(aOther.values)) + {} + PtrVector& operator=(const PtrVector&) = delete; + PtrVector& operator=(PtrVector&& aOther) + { + Swap(values, aOther.values); + return *this; + } + ~PtrVector() { for (T* value : values) { delete value; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 3405e2e0d0a..a9a5081b713 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -570,9 +570,8 @@ pref("apz.test.logging_enabled", false); pref("gfx.hidpi.enabled", 2); #endif -#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID) -// Containerless scrolling for root frames does not yet pass tests on Android -// or B2G. +#if !defined(MOZ_WIDGET_ANDROID) +// Containerless scrolling for root frames does not yet pass tests on Android. pref("layout.scroll.root-frame-containers", false); #endif diff --git a/netwerk/base/nsUDPSocket.cpp b/netwerk/base/nsUDPSocket.cpp index 2a43f721d49..2b2a5d68e85 100644 --- a/netwerk/base/nsUDPSocket.cpp +++ b/netwerk/base/nsUDPSocket.cpp @@ -660,7 +660,9 @@ nsUDPSocket::OnSocketReady(PRFileDesc *fd, int16_t outFlags) PRNetAddr prClientAddr; uint32_t count; - char buff[1500]; + // Bug 1165423 - using 8k here because the packet could be larger + // than the MTU with fragmentation + char buff[8 * 1024]; count = PR_RecvFrom(mFD, buff, sizeof(buff), 0, &prClientAddr, PR_INTERVAL_NO_WAIT); if (count < 1) { diff --git a/testing/mozbase/mozinstall/mozinstall/mozinstall.py b/testing/mozbase/mozinstall/mozinstall/mozinstall.py index d255efa9cb4..2360660fe47 100755 --- a/testing/mozbase/mozinstall/mozinstall/mozinstall.py +++ b/testing/mozbase/mozinstall/mozinstall/mozinstall.py @@ -82,10 +82,7 @@ def get_binary(path, app_name): break if not binary: - # The expected binary has not been found. Make sure we clean the - # install folder to remove any traces - mozfile.remove(path) - + # The expected binary has not been found. raise InvalidBinary('"%s" does not contain a valid binary.' % path) return binary diff --git a/toolkit/components/filepicker/nsFilePicker.js b/toolkit/components/filepicker/nsFilePicker.js index 25156c4ac55..dc3ad70e4b9 100644 --- a/toolkit/components/filepicker/nsFilePicker.js +++ b/toolkit/components/filepicker/nsFilePicker.js @@ -93,7 +93,7 @@ nsFilePicker.prototype = { /* readonly attribute nsISimpleEnumerator files; */ get files() { return this.mFilesEnumerator; }, - /* readonly attribute nsIDOMFile domfile; */ + /* readonly attribute DOM File domfile; */ get domfile() { let enumerator = this.domfiles; return enumerator ? enumerator.mFiles[0] : null; diff --git a/toolkit/modules/PropertyListUtils.jsm b/toolkit/modules/PropertyListUtils.jsm index 8602a4e4651..436caef9fe0 100644 --- a/toolkit/modules/PropertyListUtils.jsm +++ b/toolkit/modules/PropertyListUtils.jsm @@ -83,7 +83,7 @@ this.PropertyListUtils = Object.freeze({ * The reaon for failure is reported to the Error Console. */ read: function PLU_read(aFile, aCallback) { - if (!(aFile instanceof Ci.nsILocalFile || aFile instanceof Ci.nsIDOMFile)) + if (!(aFile instanceof Ci.nsILocalFile || aFile instanceof File)) throw new Error("aFile is not a file object"); if (typeof(aCallback) != "function") throw new Error("Invalid value for aCallback"); diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 07cc3013462..0180e519bf5 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -103,6 +103,10 @@ #ifndef PROCESS_DEP_ENABLE #define PROCESS_DEP_ENABLE 0x1 #endif + +#if defined(MOZ_CONTENT_SANDBOX) +#include "nsIUUIDGenerator.h" +#endif #endif #ifdef ACCESSIBILITY @@ -583,6 +587,116 @@ CanShowProfileManager() return true; } +#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) +static already_AddRefed +GetAndCleanLowIntegrityTemp(const nsAString& aTempDirSuffix) +{ + // Get the base low integrity Mozilla temp directory. + nsCOMPtr lowIntegrityTemp; + nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOW_INTEGRITY_TEMP_BASE, + getter_AddRefs(lowIntegrityTemp)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + // Append our profile specific temp name. + rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + aTempDirSuffix); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + rv = lowIntegrityTemp->Remove(/* aRecursive */ true); + if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) { + NS_WARNING("Failed to delete low integrity temp directory."); + return nullptr; + } + + return lowIntegrityTemp.forget(); +} + +static void +SetUpSandboxEnvironment() +{ + // A low integrity temp only currently makes sense for Vista and later, e10s + // and sandbox pref level 1. + if (!IsVistaOrLater() || !BrowserTabsRemoteAutostart() || + Preferences::GetInt("security.sandbox.content.level") != 1) { + return; + } + + // Get (and create if blank) temp directory suffix pref. + nsresult rv; + nsAdoptingString tempDirSuffix = + Preferences::GetString("security.sandbox.content.tempDirSuffix"); + if (tempDirSuffix.IsEmpty()) { + nsCOMPtr uuidgen = + do_GetService("@mozilla.org/uuid-generator;1", &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsID uuid; + rv = uuidgen->GenerateUUIDInPlace(&uuid); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + char uuidChars[NSID_LENGTH]; + uuid.ToProvidedString(uuidChars); + tempDirSuffix.AssignASCII(uuidChars); + + // Save the pref to be picked up later. + rv = Preferences::SetCString("security.sandbox.content.tempDirSuffix", + uuidChars); + if (NS_WARN_IF(NS_FAILED(rv))) { + // If we fail to save the pref we don't want to create the temp dir, + // because we won't be able to clean it up later. + return; + } + + nsCOMPtr prefsvc = Preferences::GetService(); + if (!prefsvc || NS_FAILED(prefsvc->SavePrefFile(nullptr))) { + // Again, if we fail to save the pref file we might not be able to clean + // up the temp directory, so don't create one. + NS_WARNING("Failed to save pref file, cannot create temp dir."); + return; + } + } + + // Get (and clean up if still there) the low integrity Mozilla temp directory. + nsCOMPtr lowIntegrityTemp = GetAndCleanLowIntegrityTemp(tempDirSuffix); + if (!lowIntegrityTemp) { + NS_WARNING("Failed to get or clean low integrity Mozilla temp directory."); + return; + } + + rv = lowIntegrityTemp->Create(nsIFile::DIRECTORY_TYPE, 0700); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } +} + +static void +CleanUpSandboxEnvironment() +{ + // We can't have created a low integrity temp before Vista. + if (!IsVistaOrLater()) { + return; + } + + // Get temp directory suffix pref. + nsAdoptingString tempDirSuffix = + Preferences::GetString("security.sandbox.content.tempDirSuffix"); + if (tempDirSuffix.IsEmpty()) { + return; + } + + // Get and remove the low integrity Mozilla temp directory. + // This function already warns if the deletion fails. + unused << GetAndCleanLowIntegrityTemp(tempDirSuffix); +} +#endif + bool gSafeMode = false; /** @@ -4081,6 +4195,10 @@ XREMain::XRE_mainRun() } #endif /* MOZ_INSTRUMENT_EVENT_LOOP */ +#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) + SetUpSandboxEnvironment(); +#endif + { rv = appStartup->Run(); if (NS_FAILED(rv)) { @@ -4089,6 +4207,10 @@ XREMain::XRE_mainRun() } } +#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) + CleanUpSandboxEnvironment(); +#endif + return rv; } diff --git a/widget/nsBaseFilePicker.cpp b/widget/nsBaseFilePicker.cpp index 7576b6cd498..37aec317d8e 100644 --- a/widget/nsBaseFilePicker.cpp +++ b/widget/nsBaseFilePicker.cpp @@ -96,7 +96,7 @@ public: return NS_ERROR_FAILURE; } - nsCOMPtr domFile = File::CreateFromFile(mParent, localFile); + nsCOMPtr domFile = File::CreateFromFile(mParent, localFile); domFile.forget(aResult); return NS_OK; } @@ -311,7 +311,7 @@ nsBaseFilePicker::GetMode(int16_t* aMode) } NS_IMETHODIMP -nsBaseFilePicker::GetDomfile(nsIDOMFile** aDomfile) +nsBaseFilePicker::GetDomfile(nsISupports** aDomfile) { nsCOMPtr localFile; nsresult rv = GetFile(getter_AddRefs(localFile)); @@ -322,7 +322,7 @@ nsBaseFilePicker::GetDomfile(nsIDOMFile** aDomfile) return NS_OK; } - nsRefPtr domFile = File::CreateFromFile(mParent, localFile); + nsCOMPtr domFile = File::CreateFromFile(mParent, localFile); domFile.forget(aDomfile); return NS_OK; } diff --git a/widget/nsBaseFilePicker.h b/widget/nsBaseFilePicker.h index 1a470674631..b192a162573 100644 --- a/widget/nsBaseFilePicker.h +++ b/widget/nsBaseFilePicker.h @@ -37,7 +37,7 @@ public: NS_IMETHOD SetAddToRecentDocs(bool aFlag); NS_IMETHOD GetMode(int16_t *aMode); - NS_IMETHOD GetDomfile(nsIDOMFile** aDomfile); + NS_IMETHOD GetDomfile(nsISupports** aDomfile); NS_IMETHOD GetDomfiles(nsISimpleEnumerator** aDomfiles); protected: diff --git a/widget/nsFilePickerProxy.cpp b/widget/nsFilePickerProxy.cpp index 54a73aaa099..b1eb2911de3 100644 --- a/widget/nsFilePickerProxy.cpp +++ b/widget/nsFilePickerProxy.cpp @@ -165,7 +165,7 @@ nsFilePickerProxy::Recv__delete__(const MaybeInputFiles& aFiles, nsRefPtr file = File::Create(mParent, blobImpl); MOZ_ASSERT(file); - mDomfiles.AppendObject(file); + mDomfiles.AppendElement(file); } } @@ -178,7 +178,7 @@ nsFilePickerProxy::Recv__delete__(const MaybeInputFiles& aFiles, } NS_IMETHODIMP -nsFilePickerProxy::GetDomfile(nsIDOMFile** aDomfile) +nsFilePickerProxy::GetDomfile(nsISupports** aDomfile) { *aDomfile = nullptr; if (mDomfiles.IsEmpty()) { @@ -186,13 +186,55 @@ nsFilePickerProxy::GetDomfile(nsIDOMFile** aDomfile) } MOZ_ASSERT(mDomfiles.Length() == 1); - nsCOMPtr domfile = mDomfiles[0]; - domfile.forget(aDomfile); + nsCOMPtr blob = mDomfiles[0].get(); + blob.forget(aDomfile); return NS_OK; } +namespace { + +class SimpleEnumerator final : public nsISimpleEnumerator +{ +public: + NS_DECL_ISUPPORTS + + explicit SimpleEnumerator(const nsTArray>& aFiles) + : mFiles(aFiles) + , mIndex(0) + {} + + NS_IMETHOD + HasMoreElements(bool* aRetvalue) override + { + MOZ_ASSERT(aRetvalue); + *aRetvalue = mFiles.Length() >= mIndex; + return NS_OK; + } + + NS_IMETHOD + GetNext(nsISupports** aSupports) override + { + nsCOMPtr blob = mFiles[mIndex++].get(); + blob.forget(aSupports); + return NS_OK; + } + +private: + ~SimpleEnumerator() + {} + + nsTArray> mFiles; + uint32_t mIndex; +}; + +NS_IMPL_ISUPPORTS(SimpleEnumerator, nsISimpleEnumerator) + +} // anonymous namespace + NS_IMETHODIMP nsFilePickerProxy::GetDomfiles(nsISimpleEnumerator** aDomfiles) { - return NS_NewArrayEnumerator(aDomfiles, mDomfiles); + nsRefPtr enumerator = new SimpleEnumerator(mDomfiles); + enumerator.forget(aDomfiles); + return NS_OK; } diff --git a/widget/nsFilePickerProxy.h b/widget/nsFilePickerProxy.h index 63c50fee273..aaba9857772 100644 --- a/widget/nsFilePickerProxy.h +++ b/widget/nsFilePickerProxy.h @@ -18,6 +18,12 @@ class nsIWidget; class nsIFile; class nsPIDOMWindow; +namespace mozilla { +namespace dom { +class File; +} +} + /** This class creates a proxy file picker to be used in content processes. The file picker just collects the initialization data and when Show() is @@ -45,7 +51,7 @@ public: NS_IMETHODIMP GetFileURL(nsIURI** aFileURL) override; NS_IMETHODIMP GetFiles(nsISimpleEnumerator** aFiles) override; - NS_IMETHODIMP GetDomfile(nsIDOMFile** aFile) override; + NS_IMETHODIMP GetDomfile(nsISupports** aFile) override; NS_IMETHODIMP GetDomfiles(nsISimpleEnumerator** aFiles) override; NS_IMETHODIMP Show(int16_t* aReturn) override; @@ -59,7 +65,7 @@ private: ~nsFilePickerProxy(); void InitNative(nsIWidget*, const nsAString&) override; - nsCOMArray mDomfiles; + nsTArray> mDomfiles; nsCOMPtr mCallback; int16_t mSelectedType; diff --git a/widget/nsIFilePicker.idl b/widget/nsIFilePicker.idl index 5a0f1d4475f..c51db99a336 100644 --- a/widget/nsIFilePicker.idl +++ b/widget/nsIFilePicker.idl @@ -8,7 +8,6 @@ interface nsIFile; interface nsIURI; -interface nsIDOMFile; interface nsIDOMWindow; interface nsISimpleEnumerator; @@ -24,7 +23,7 @@ interface nsIFilePickerShownCallback : nsISupports void done(in short aResult); }; -[scriptable, uuid(f93509a0-0434-11e3-8ffd-0800200c9a66)] +[scriptable, uuid(9840d564-42c8-4d78-9a4d-71002343c918)] interface nsIFilePicker : nsISupports { const short modeOpen = 0; // Load a file or directory @@ -143,11 +142,11 @@ interface nsIFilePicker : nsISupports readonly attribute nsISimpleEnumerator files; /** - * Get the nsIDOMFile for the file. + * Get the DOM File for the file. * * @return Returns the file currently selected as File */ - readonly attribute nsIDOMFile domfile; + readonly attribute nsISupports domfile; /** * Get the enumerator for the selected files diff --git a/xpcom/io/nsDirectoryService.cpp b/xpcom/io/nsDirectoryService.cpp index 3f797e8aa1e..c2abd140aa7 100644 --- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -24,10 +24,6 @@ #include #include #include - -#if defined(MOZ_CONTENT_SANDBOX) -#include "nsIUUIDGenerator.h" -#endif #elif defined(XP_UNIX) #include #include @@ -502,7 +498,7 @@ nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv) #if defined(MOZ_CONTENT_SANDBOX) && defined(XP_WIN) static nsresult -GetLowIntegrityTemp(nsIFile** aLowIntegrityTemp) +GetLowIntegrityTempBase(nsIFile** aLowIntegrityTempBase) { nsCOMPtr localFile; nsresult rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, @@ -511,37 +507,12 @@ GetLowIntegrityTemp(nsIFile** aLowIntegrityTemp) return rv; } - nsCOMPtr uuidgen = - do_GetService("@mozilla.org/uuid-generator;1", &rv); + rv = localFile->Append(NS_LITERAL_STRING(MOZ_USER_DIR)); 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); - rv = localFile->AppendNative(NS_LITERAL_CSTRING(MOZ_USER_DIR)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = localFile->AppendNative(NS_LITERAL_CSTRING("MozTemp-") - + nsDependentCString(uuidChars)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = localFile->Create(nsIFile::DIRECTORY_TYPE, 0700); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - localFile.forget(aLowIntegrityTemp); + localFile.forget(aLowIntegrityTempBase); return rv; } #endif @@ -722,8 +693,8 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent, #if defined(MOZ_CONTENT_SANDBOX) } else if (inAtom == nsDirectoryService::sLocalAppdataLow) { rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, getter_AddRefs(localFile)); - } else if (inAtom == nsDirectoryService::sLowIntegrityTemp) { - rv = GetLowIntegrityTemp(getter_AddRefs(localFile)); + } else if (inAtom == nsDirectoryService::sLowIntegrityTempBase) { + rv = GetLowIntegrityTempBase(getter_AddRefs(localFile)); #endif } else if (inAtom == nsDirectoryService::sPrinthood) { rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile)); diff --git a/xpcom/io/nsDirectoryServiceAtomList.h b/xpcom/io/nsDirectoryServiceAtomList.h index b344da11ead..38a2f0e9d6f 100644 --- a/xpcom/io/nsDirectoryServiceAtomList.h +++ b/xpcom/io/nsDirectoryServiceAtomList.h @@ -74,7 +74,7 @@ DIR_ATOM(sAppdata, NS_WIN_APPDATA_DIR) DIR_ATOM(sLocalAppdata, NS_WIN_LOCAL_APPDATA_DIR) #if defined(MOZ_CONTENT_SANDBOX) DIR_ATOM(sLocalAppdataLow, NS_WIN_LOCAL_APPDATA_LOW_DIR) -DIR_ATOM(sLowIntegrityTemp, NS_WIN_LOW_INTEGRITY_TEMP) +DIR_ATOM(sLowIntegrityTempBase, NS_WIN_LOW_INTEGRITY_TEMP_BASE) #endif DIR_ATOM(sPrinthood, NS_WIN_PRINTHOOD) DIR_ATOM(sWinCookiesDirectory, NS_WIN_COOKIES_DIR) diff --git a/xpcom/io/nsDirectoryServiceDefs.h b/xpcom/io/nsDirectoryServiceDefs.h index 2a84b80f33e..0bdc5e39059 100644 --- a/xpcom/io/nsDirectoryServiceDefs.h +++ b/xpcom/io/nsDirectoryServiceDefs.h @@ -131,7 +131,7 @@ #define NS_WIN_LOCAL_APPDATA_DIR "LocalAppData" #if defined(MOZ_CONTENT_SANDBOX) #define NS_WIN_LOCAL_APPDATA_LOW_DIR "LocalAppDataLow" - #define NS_WIN_LOW_INTEGRITY_TEMP "LowTmpD" + #define NS_WIN_LOW_INTEGRITY_TEMP_BASE "LowTmpDBase" #endif #define NS_WIN_PRINTHOOD "PrntHd" #define NS_WIN_COOKIES_DIR "CookD"