Bug 1299500 - Get rid of DeviceStorage API - part 10 - DeviceStorage, r=ehsan, r=billm, a=lizzard
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 08 Mar 2017 20:15:45 +0100
changeset 379248 4816ac7ebaf45d4d43fcffcb5a7e2f5c142a4883
parent 379247 6db8154a25428c153e438acbb2a98200cf0806f3
child 379249 57035f3bfd55dbbb53873d5322efa48c655a4fa4
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, billm, lizzard
bugs1299500
milestone53.0
Bug 1299500 - Get rid of DeviceStorage API - part 10 - DeviceStorage, r=ehsan, r=billm, a=lizzard
b2g/chrome/content/devtools/adb.js
dom/bindings/Bindings.conf
dom/devicestorage/DeviceStorage.h
dom/devicestorage/DeviceStorageFileDescriptor.h
dom/devicestorage/DeviceStorageRequestChild.cpp
dom/devicestorage/DeviceStorageRequestChild.h
dom/devicestorage/DeviceStorageRequestParent.cpp
dom/devicestorage/DeviceStorageRequestParent.h
dom/devicestorage/DeviceStorageStatics.cpp
dom/devicestorage/DeviceStorageStatics.h
dom/devicestorage/PDeviceStorageRequest.ipdl
dom/devicestorage/moz.build
dom/devicestorage/nsDeviceStorage.cpp
dom/devicestorage/nsDeviceStorage.h
dom/devicestorage/test/chrome.ini
dom/devicestorage/test/devicestorage_common.js
dom/devicestorage/test/mochitest.ini
dom/devicestorage/test/remove_testing_directory.js
dom/devicestorage/test/test_823965.html
dom/devicestorage/test/test_add.html
dom/devicestorage/test/test_addCorrectType.html
dom/devicestorage/test/test_app_permissions.html
dom/devicestorage/test/test_available.html
dom/devicestorage/test/test_basic.html
dom/devicestorage/test/test_dirs.html
dom/devicestorage/test/test_diskSpace.html
dom/devicestorage/test/test_dotdot.html
dom/devicestorage/test/test_enumerate.html
dom/devicestorage/test/test_enumerateMultipleContinue.html
dom/devicestorage/test/test_enumerateNoParam.html
dom/devicestorage/test/test_enumerateOptions.html
dom/devicestorage/test/test_freeSpace.html
dom/devicestorage/test/test_fs_app_permissions.html
dom/devicestorage/test/test_fs_appendFile.html
dom/devicestorage/test/test_fs_basic.html
dom/devicestorage/test/test_fs_createDirectory.html
dom/devicestorage/test/test_fs_createFile.html
dom/devicestorage/test/test_fs_get.html
dom/devicestorage/test/test_fs_getFilesAndDirectories.html
dom/devicestorage/test/test_fs_remove.html
dom/devicestorage/test/test_lastModificationFilter.html
dom/devicestorage/test/test_overrideDir.html
dom/devicestorage/test/test_overwrite.html
dom/devicestorage/test/test_sanity.html
dom/devicestorage/test/test_usedSpace.html
dom/devicestorage/test/test_watch.html
dom/devicestorage/test/test_watchOther.html
dom/filesystem/DeviceStorageFileSystem.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/moz.build
dom/moz.build
dom/webidl/DeviceStorage.webidl
dom/webidl/moz.build
layout/build/nsLayoutStatics.cpp
mobile/android/components/ContentPermissionPrompt.js
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
netwerk/test/mochitests/signed_web_packaged_app.sjs
toolkit/components/jsdownloads/src/DownloadIntegration.jsm
toolkit/components/jsdownloads/src/DownloadPlatform.cpp
toolkit/components/jsdownloads/test/unit/common_test_Download.js
toolkit/content/devicestorage.properties
toolkit/content/jar.mn
uriloader/exthandler/nsExternalHelperAppService.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/GeneratedJNIWrappers.cpp
widget/android/GeneratedJNIWrappers.h
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
--- a/b2g/chrome/content/devtools/adb.js
+++ b/b2g/chrome/content/devtools/adb.js
@@ -83,48 +83,16 @@ var AdbController = {
       debug("ADB timer expired - disabling ADB\n");
       navigator.mozSettings.createLock().set(
         {'debugger.remote-mode': 'disabled'});
     }
   },
 
   updateState: function() {
     this.umsActive = false;
-    this.storages = navigator.getDeviceStorages('sdcard');
-    this.updateStorageState(0);
-  },
-
-  updateStorageState: function(storageIndex) {
-    if (storageIndex >= this.storages.length) {
-      // We've iterated through all of the storage objects, now we can
-      // really do updateStateInternal.
-      this.updateStateInternal();
-      return;
-    }
-    let storage = this.storages[storageIndex];
-    DEBUG && debug("Checking availability of storage: '" + storage.storageName + "'");
-
-    let req = storage.available();
-    req.onsuccess = function(e) {
-      DEBUG && debug("Storage: '" + storage.storageName + "' is '" + e.target.result + "'");
-      if (e.target.result == 'shared') {
-        // We've found a storage area that's being shared with the PC.
-        // We can stop looking now.
-        this.umsActive = true;
-        this.updateStateInternal();
-        return;
-      }
-      this.updateStorageState(storageIndex + 1);
-    }.bind(this);
-    req.onerror = function(e) {
-
-      Cu.reportError("AdbController: error querying storage availability for '" +
-                     this.storages[storageIndex].storageName + "' (ignoring)\n");
-      this.updateStorageState(storageIndex + 1);
-    }.bind(this);
   },
 
   updateStateInternal: function() {
     DEBUG && debug("updateStateInternal: called");
 
     if (this.remoteDebuggerEnabled === undefined ||
         this.lockEnabled === undefined ||
         this.locked === undefined) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -305,21 +305,16 @@ DOMInterfaces = {
 'DeviceAcceleration': {
     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
 },
 
 'DeviceRotationRate': {
     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
 },
 
-'DeviceStorage': {
-    'nativeType': 'nsDOMDeviceStorage',
-    'headerFile': 'DeviceStorage.h',
-},
-
 'Document': {
     'nativeType': 'nsIDocument',
 },
 
 'DominatorTree': {
     'nativeType': 'mozilla::devtools::DominatorTree'
 },
 
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorage.h
+++ /dev/null
@@ -1,382 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DeviceStorage_h
-#define DeviceStorage_h
-
-#include "nsAutoPtr.h"
-#include "nsIFile.h"
-#include "nsIPrincipal.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/dom/DOMRequest.h"
-#include "nsWeakReference.h"
-
-#define DEVICESTORAGE_PICTURES   "pictures"
-#define DEVICESTORAGE_VIDEOS     "videos"
-#define DEVICESTORAGE_MUSIC      "music"
-#define DEVICESTORAGE_APPS       "apps"
-#define DEVICESTORAGE_SDCARD     "sdcard"
-#define DEVICESTORAGE_CRASHES    "crashes"
-
-class nsIInputStream;
-class nsIOutputStream;
-struct DeviceStorageFileDescriptor;
-#ifdef MOZ_WIDGET_GONK
-class nsIVolume;
-#endif
-
-namespace mozilla {
-class EventListenerManager;
-namespace dom {
-class Blob;
-struct DeviceStorageEnumerationParameters;
-class DOMCursor;
-class DOMRequest;
-class Promise;
-class DeviceStorageFileSystem;
-} // namespace dom
-namespace ipc {
-class FileDescriptor;
-class PrincipalInfo;
-} // namespace ipc
-} // namespace mozilla
-
-class DeviceStorageRequest;
-class DeviceStorageCursorRequest;
-class DeviceStorageRequestManager;
-class nsDOMDeviceStorageCursor;
-
-class DeviceStorageFile final
-  : public nsISupports {
-public:
-  nsCOMPtr<nsIFile> mFile;
-  nsString mStorageType;
-  nsString mStorageName;
-  nsString mRootDir;
-  nsString mPath;
-  bool mEditable;
-  nsString mMimeType;
-  uint64_t mLength;
-  uint64_t mLastModifiedDate;
-
-  // Used when the path will be set later via SetPath.
-  DeviceStorageFile(const nsAString& aStorageType,
-                    const nsAString& aStorageName);
-  // Used for non-enumeration purposes.
-  DeviceStorageFile(const nsAString& aStorageType,
-                    const nsAString& aStorageName,
-                    const nsAString& aPath);
-  // Used for enumerations. When you call Enumerate, you can pass in a
-  // directory to enumerate and the results that are returned are relative to
-  // that directory, files related to an enumeration need to know the "root of
-  // the enumeration" directory.
-  DeviceStorageFile(const nsAString& aStorageType,
-                    const nsAString& aStorageName,
-                    const nsAString& aRootDir,
-                    const nsAString& aPath);
-
-  void SetPath(const nsAString& aPath);
-  void SetEditable(bool aEditable);
-
-  static already_AddRefed<DeviceStorageFile>
-  CreateUnique(nsAString& aFileName,
-               uint32_t aFileType,
-               uint32_t aFileAttributes);
-
-  static already_AddRefed<DeviceStorageFile>
-  CreateUnique(const nsAString& aStorageType,
-               const nsAString& aStorageName,
-               nsAString& aFileName,
-               uint32_t aFileType,
-               uint32_t aFileAttributes);
-
-  NS_DECL_THREADSAFE_ISUPPORTS
-
-  bool IsAvailable();
-  void GetFullPath(nsAString& aFullPath);
-
-  // we want to make sure that the names of file can't reach
-  // outside of the type of storage the user asked for.
-  bool IsSafePath() const;
-  bool ValidateAndSplitPath(const nsAString& aPath,
-                            nsTArray<nsString>* aParts = nullptr) const;
-
-  void Dump(const char* label);
-
-  nsresult Remove();
-  nsresult Write(nsIInputStream* aInputStream);
-  nsresult Write(InfallibleTArray<uint8_t>& bits);
-  nsresult Append(nsIInputStream* aInputStream);
-  nsresult Append(nsIInputStream* aInputStream,
-                  nsIOutputStream* aOutputStream);
-  void CollectFiles(nsTArray<RefPtr<DeviceStorageFile> >& aFiles,
-                    PRTime aSince = 0);
-  void collectFilesInternal(nsTArray<RefPtr<DeviceStorageFile> >& aFiles,
-                            PRTime aSince, nsAString& aRootPath);
-
-  void AccumDiskUsage(uint64_t* aPicturesSoFar, uint64_t* aVideosSoFar,
-                      uint64_t* aMusicSoFar, uint64_t* aTotalSoFar);
-
-  void GetStorageFreeSpace(int64_t* aSoFar);
-  void GetStatus(nsAString& aStatus);
-  void GetStorageStatus(nsAString& aStatus);
-  void DoFormat(nsAString& aStatus);
-  void DoMount(nsAString& aStatus);
-  void DoUnmount(nsAString& aStatus);
-  static void GetRootDirectoryForType(const nsAString& aStorageType,
-                                      const nsAString& aStorageName,
-                                      nsIFile** aFile);
-
-  nsresult CalculateSizeAndModifiedDate();
-  nsresult CalculateMimeType();
-  nsresult CreateFileDescriptor(mozilla::ipc::FileDescriptor& aFileDescriptor);
-
-private:
-  ~DeviceStorageFile() {}
-  void Init();
-  void AppendRelativePath(const nsAString& aPath);
-  void AccumDirectoryUsage(nsIFile* aFile,
-                           uint64_t* aPicturesSoFar,
-                           uint64_t* aVideosSoFar,
-                           uint64_t* aMusicSoFar,
-                           uint64_t* aTotalSoFar);
-};
-
-#define NS_DOM_DEVICE_STORAGE_CID \
-  { 0xe4a9b969, 0x81fe, 0x44f1, \
-    { 0xaa, 0x0c, 0x9e, 0x16, 0x64, 0x86, 0x2a, 0xd5 } }
-
-class nsDOMDeviceStorage final
-  : public mozilla::DOMEventTargetHelper
-  , public nsSupportsWeakReference
-{
-  typedef mozilla::ErrorResult ErrorResult;
-  typedef mozilla::dom::DeviceStorageEnumerationParameters
-    EnumerationParameters;
-  typedef mozilla::dom::DOMCursor DOMCursor;
-  typedef mozilla::dom::DOMRequest DOMRequest;
-  typedef mozilla::dom::Promise Promise;
-  typedef mozilla::dom::DeviceStorageFileSystem DeviceStorageFileSystem;
-public:
-  typedef nsTArray<nsString> VolumeNameArray;
-
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_DEVICE_STORAGE_CID)
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
-
-  void EventListenerWasAdded(const nsAString& aType,
-                             ErrorResult& aRv,
-                             JSCompartment* aCompartment) override;
-
-  explicit nsDOMDeviceStorage(nsPIDOMWindowInner* aWindow);
-
-  static int InstanceCount() { return sInstanceCount; }
-
-  static void InvalidateVolumeCaches();
-
-  nsresult Init(nsPIDOMWindowInner* aWindow, const nsAString& aType,
-                const nsAString& aVolName);
-
-  bool IsAvailable();
-  bool IsFullPath(const nsAString& aPath)
-  {
-    return aPath.Length() > 0 && aPath.CharAt(0) == '/';
-  }
-
-  void SetRootDirectoryForType(const nsAString& aType,
-                               const nsAString& aVolName);
-
-  // WebIDL
-  nsPIDOMWindowInner*
-  GetParentObject() const
-  {
-    return GetOwner();
-  }
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  IMPL_EVENT_HANDLER(change)
-
-  already_AddRefed<DOMRequest>
-  Add(mozilla::dom::Blob* aBlob, ErrorResult& aRv);
-  already_AddRefed<DOMRequest>
-  AddNamed(mozilla::dom::Blob* aBlob, const nsAString& aPath, ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  AppendNamed(mozilla::dom::Blob* aBlob, const nsAString& aPath,
-              ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Get(const nsAString& aPath, ErrorResult& aRv)
-  {
-    return GetInternal(aPath, false, aRv);
-  }
-  already_AddRefed<DOMRequest>
-  GetEditable(const nsAString& aPath, ErrorResult& aRv)
-  {
-    return GetInternal(aPath, true, aRv);
-  }
-  already_AddRefed<DOMRequest>
-  Delete(const nsAString& aPath, ErrorResult& aRv);
-
-  already_AddRefed<DOMCursor>
-  Enumerate(const EnumerationParameters& aOptions, ErrorResult& aRv)
-  {
-    return Enumerate(NullString(), aOptions, aRv);
-  }
-  already_AddRefed<DOMCursor>
-  Enumerate(const nsAString& aPath, const EnumerationParameters& aOptions,
-            ErrorResult& aRv);
-  already_AddRefed<DOMCursor>
-  EnumerateEditable(const EnumerationParameters& aOptions, ErrorResult& aRv)
-  {
-    return EnumerateEditable(NullString(), aOptions, aRv);
-  }
-  already_AddRefed<DOMCursor>
-  EnumerateEditable(const nsAString& aPath,
-                    const EnumerationParameters& aOptions, ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest> FreeSpace(ErrorResult& aRv);
-  already_AddRefed<DOMRequest> UsedSpace(ErrorResult& aRv);
-  already_AddRefed<DOMRequest> Available(ErrorResult& aRv);
-  already_AddRefed<DOMRequest> Format(ErrorResult& aRv);
-  already_AddRefed<DOMRequest> StorageStatus(ErrorResult& aRv);
-  already_AddRefed<DOMRequest> Mount(ErrorResult& aRv);
-  already_AddRefed<DOMRequest> Unmount(ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest> CreateFileDescriptor(const nsAString& aPath,
-                                                    DeviceStorageFileDescriptor* aDSFD,
-                                                    ErrorResult& aRv);
-
-  bool CanBeMounted();
-  bool CanBeFormatted();
-  bool CanBeShared();
-  bool IsRemovable();
-  bool LowDiskSpace();
-  bool Default();
-  void GetStorageName(nsAString& aStorageName);
-
-  already_AddRefed<Promise>
-  GetRoot(ErrorResult& aRv);
-
-  static void
-  CreateDeviceStorageFor(nsPIDOMWindowInner* aWin,
-                         const nsAString& aType,
-                         nsDOMDeviceStorage** aStore);
-
-  static void
-  CreateDeviceStorageByNameAndType(nsPIDOMWindowInner* aWin,
-                                   const nsAString& aName,
-                                   const nsAString& aType,
-                                   nsDOMDeviceStorage** aStore);
-
-  bool Equals(nsPIDOMWindowInner* aWin,
-              const nsAString& aName,
-              const nsAString& aType);
-
-  void Shutdown();
-
-  static void GetOrderedVolumeNames(const nsAString& aType,
-                                    nsTArray<nsString>& aVolumeNames);
-
-  static void GetOrderedVolumeNames(nsTArray<nsString>& aVolumeNames);
-
-  static void GetDefaultStorageName(const nsAString& aStorageType,
-                                    nsAString& aStorageName);
-
-  static bool ParseFullPath(const nsAString& aFullPath,
-                            nsAString& aOutStorageName,
-                            nsAString& aOutStoragePath);
-
-  // DeviceStorageStatics callbacks
-  void OnFileWatcherUpdate(const nsCString& aData, DeviceStorageFile* aFile);
-  void OnDiskSpaceWatcher(bool aLowDiskSpace);
-  void OnWritableNameChanged();
-#ifdef MOZ_WIDGET_GONK
-  void OnVolumeStateChanged(nsIVolume* aVolume);
-#endif
-
-  uint32_t CreateDOMRequest(DOMRequest** aRequest, ErrorResult& aRv);
-  uint32_t CreateDOMCursor(DeviceStorageCursorRequest* aRequest,
-                           nsDOMDeviceStorageCursor** aCursor,
-                           ErrorResult& aRv);
-  already_AddRefed<DOMRequest> CreateAndRejectDOMRequest(const char *aReason,
-                                                         ErrorResult& aRv);
-
-  nsresult CheckPermission(already_AddRefed<DeviceStorageRequest>&& aRequest);
-
-  bool IsOwningThread();
-  nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
-
-private:
-  ~nsDOMDeviceStorage();
-
-  static nsresult CheckPrincipal(nsPIDOMWindowInner* aWindow,
-                                 bool aIsAppsStorage,
-                                 nsIPrincipal** aPrincipal);
-
-  already_AddRefed<DOMRequest>
-  AddOrAppendNamed(mozilla::dom::Blob* aBlob, const nsAString& aPath,
-                   bool aCreate, ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  GetInternal(const nsAString& aPath, bool aEditable, ErrorResult& aRv);
-
-  void
-  DeleteInternal(nsPIDOMWindowInner* aWin, const nsAString& aPath,
-                 DOMRequest* aRequest);
-
-  already_AddRefed<DOMCursor>
-  EnumerateInternal(const nsAString& aName,
-                    const EnumerationParameters& aOptions, bool aEditable,
-                    ErrorResult& aRv);
-
-  static int sInstanceCount;
-
-  nsString mStorageType;
-  nsCOMPtr<nsIFile> mRootDirectory;
-  nsString mStorageName;
-  bool mIsShareable;
-  bool mIsRemovable;
-
-  already_AddRefed<nsDOMDeviceStorage> GetStorage(const nsAString& aFullPath,
-                                                  nsAString& aOutStoragePath);
-  already_AddRefed<nsDOMDeviceStorage>
-    GetStorageByName(const nsAString &aStorageName);
-
-  static already_AddRefed<nsDOMDeviceStorage>
-    GetStorageByNameAndType(nsPIDOMWindowInner* aWin,
-                            const nsAString& aStorageName,
-                            const nsAString& aType);
-
-  bool mIsDefaultLocation;
-
-  nsresult Notify(const char* aReason, class DeviceStorageFile* aFile);
-
-  friend class WatchFileEvent;
-  friend class DeviceStorageRequest;
-
-  static mozilla::StaticAutoPtr<nsTArray<nsString>> sVolumeNameCache;
-
-#ifdef MOZ_WIDGET_GONK
-  nsString mLastStatus;
-  nsString mLastStorageStatus;
-  void DispatchStatusChangeEvent(nsAString& aStatus);
-  void DispatchStorageStatusChangeEvent(nsAString& aStorageStatus);
-#endif
-
-  uint64_t mInnerWindowID;
-  RefPtr<DeviceStorageFileSystem> mFileSystem;
-  RefPtr<DeviceStorageRequestManager> mManager;
-  nsAutoPtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
-  nsCOMPtr<nsIThread> mOwningThread;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMDeviceStorage, NS_DOM_DEVICE_STORAGE_CID)
-
-#endif
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageFileDescriptor.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DeviceStorageFileDescriptor_h
-#define DeviceStorageFileDescriptor_h
-
-#include "mozilla/ipc/FileDescriptor.h"
-
-struct DeviceStorageFileDescriptor final
-{
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceStorageFileDescriptor)
-  RefPtr<DeviceStorageFile> mDSFile;
-  mozilla::ipc::FileDescriptor mFileDescriptor;
-private:
-  ~DeviceStorageFileDescriptor() {}
-};
-
-#endif
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "DeviceStorageRequestChild.h"
-#include "DeviceStorageFileDescriptor.h"
-#include "nsDeviceStorage.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/ipc/BlobChild.h"
-
-namespace mozilla {
-namespace dom {
-namespace devicestorage {
-
-DeviceStorageRequestChild::DeviceStorageRequestChild()
-{
-  MOZ_COUNT_CTOR(DeviceStorageRequestChild);
-}
-
-DeviceStorageRequestChild::DeviceStorageRequestChild(DeviceStorageRequest* aRequest)
-  : mRequest(aRequest)
-{
-  MOZ_ASSERT(aRequest);
-  MOZ_COUNT_CTOR(DeviceStorageRequestChild);
-}
-
-DeviceStorageRequestChild::~DeviceStorageRequestChild() {
-  MOZ_COUNT_DTOR(DeviceStorageRequestChild);
-}
-
-mozilla::ipc::IPCResult
-DeviceStorageRequestChild::
-  Recv__delete__(const DeviceStorageResponseValue& aValue)
-{
-  switch (aValue.type()) {
-
-    case DeviceStorageResponseValue::TErrorResponse:
-    {
-      DS_LOG_INFO("error %u", mRequest->GetId());
-      ErrorResponse r = aValue;
-      mRequest->Reject(r.error());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TSuccessResponse:
-    {
-      DS_LOG_INFO("success %u", mRequest->GetId());
-      nsString fullPath;
-      mRequest->GetFile()->GetFullPath(fullPath);
-      mRequest->Resolve(fullPath);
-      break;
-    }
-
-    case DeviceStorageResponseValue::TFileDescriptorResponse:
-    {
-      DS_LOG_INFO("fd %u", mRequest->GetId());
-      FileDescriptorResponse r = aValue;
-
-      DeviceStorageFile* file = mRequest->GetFile();
-      DeviceStorageFileDescriptor* descriptor = mRequest->GetFileDescriptor();
-      nsString fullPath;
-      file->GetFullPath(fullPath);
-      descriptor->mDSFile = file;
-      descriptor->mFileDescriptor = r.fileDescriptor();
-      mRequest->Resolve(fullPath);
-      break;
-    }
-
-    case DeviceStorageResponseValue::TBlobResponse:
-    {
-      DS_LOG_INFO("blob %u", mRequest->GetId());
-      BlobResponse r = aValue;
-      BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
-      RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl();
-      mRequest->Resolve(blobImpl.get());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TFreeSpaceStorageResponse:
-    {
-      DS_LOG_INFO("free %u", mRequest->GetId());
-      FreeSpaceStorageResponse r = aValue;
-      mRequest->Resolve(r.freeBytes());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TUsedSpaceStorageResponse:
-    {
-      DS_LOG_INFO("used %u", mRequest->GetId());
-      UsedSpaceStorageResponse r = aValue;
-      mRequest->Resolve(r.usedBytes());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TFormatStorageResponse:
-    {
-      DS_LOG_INFO("format %u", mRequest->GetId());
-      FormatStorageResponse r = aValue;
-      mRequest->Resolve(r.mountState());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TMountStorageResponse:
-    {
-      DS_LOG_INFO("mount %u", mRequest->GetId());
-      MountStorageResponse r = aValue;
-      mRequest->Resolve(r.storageStatus());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TUnmountStorageResponse:
-    {
-      DS_LOG_INFO("unmount %u", mRequest->GetId());
-      UnmountStorageResponse r = aValue;
-      mRequest->Resolve(r.storageStatus());
-      break;
-    }
-
-    case DeviceStorageResponseValue::TEnumerationResponse:
-    {
-      DS_LOG_INFO("enumerate %u", mRequest->GetId());
-      EnumerationResponse r = aValue;
-      auto request = static_cast<DeviceStorageCursorRequest*>(mRequest.get());
-      uint32_t count = r.paths().Length();
-      request->AddFiles(count);
-      for (uint32_t i = 0; i < count; i++) {
-        RefPtr<DeviceStorageFile> dsf
-          = new DeviceStorageFile(r.type(), r.paths()[i].storageName(),
-                                  r.rootdir(), r.paths()[i].name());
-        request->AddFile(dsf.forget());
-      }
-      request->Continue();
-      break;
-    }
-
-    default:
-    {
-      DS_LOG_ERROR("unknown %u", mRequest->GetId());
-      MOZ_CRASH("not reached");
-      break;
-    }
-  }
-  return IPC_OK();
-}
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageRequestChild.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_devicestorage_DeviceStorageRequestChild_h
-#define mozilla_dom_devicestorage_DeviceStorageRequestChild_h
-
-#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
-
-class DeviceStorageFile;
-class DeviceStorageRequest;
-struct DeviceStorageFileDescriptor;
-
-namespace mozilla {
-namespace dom {
-
-namespace devicestorage {
-
-class DeviceStorageRequestChildCallback
-{
-  public:
-    virtual void RequestComplete() = 0;
-};
-
-class DeviceStorageRequestChild : public PDeviceStorageRequestChild
-{
-public:
-  DeviceStorageRequestChild();
-  explicit DeviceStorageRequestChild(DeviceStorageRequest* aRequest);
-  ~DeviceStorageRequestChild();
-
-  virtual mozilla::ipc::IPCResult Recv__delete__(const DeviceStorageResponseValue& value);
-
-private:
-  RefPtr<DeviceStorageRequest> mRequest;
-};
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageRequestParent.cpp
+++ /dev/null
@@ -1,595 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DeviceStorageRequestParent.h"
-#include "nsIMIMEService.h"
-#include "nsCExternalHandlerService.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/ipc/BlobParent.h"
-#include "ContentParent.h"
-#include "nsProxyRelease.h"
-#include "mozilla/Preferences.h"
-#include "nsNetCID.h"
-
-namespace mozilla {
-namespace dom {
-namespace devicestorage {
-
-DeviceStorageRequestParent::DeviceStorageRequestParent(
-  const DeviceStorageParams& aParams)
-  : mParams(aParams)
-  , mMutex("DeviceStorageRequestParent::mMutex")
-  , mActorDestroyed(false)
-{
-  MOZ_COUNT_CTOR(DeviceStorageRequestParent);
-
-  DebugOnly<DeviceStorageUsedSpaceCache*> usedSpaceCache
-    = DeviceStorageUsedSpaceCache::CreateOrGet();
-  MOZ_ASSERT(usedSpaceCache);
-}
-
-void
-DeviceStorageRequestParent::Dispatch()
-{
-  RefPtr<CancelableRunnable> r;
-  switch (mParams.type()) {
-    case DeviceStorageParams::TDeviceStorageAddParams:
-    {
-      DeviceStorageAddParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
-
-      BlobParent* bp = static_cast<BlobParent*>(p.blobParent());
-      RefPtr<BlobImpl> blobImpl = bp->GetBlobImpl();
-
-      ErrorResult rv;
-      nsCOMPtr<nsIInputStream> stream;
-      blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
-      MOZ_ASSERT(!rv.Failed());
-
-      r = new WriteFileEvent(this, dsf.forget(), stream,
-                             DEVICE_STORAGE_REQUEST_CREATE);
-      break;
-    }
-
-    case DeviceStorageParams::TDeviceStorageAppendParams:
-    {
-      DeviceStorageAppendParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
-
-      BlobParent* bp = static_cast<BlobParent*>(p.blobParent());
-      RefPtr<BlobImpl> blobImpl = bp->GetBlobImpl();
-
-      ErrorResult rv;
-      nsCOMPtr<nsIInputStream> stream;
-      blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
-      MOZ_ASSERT(!rv.Failed());
-
-      r = new WriteFileEvent(this, dsf.forget(), stream,
-                             DEVICE_STORAGE_REQUEST_APPEND);
-      break;
-    }
-
-    case DeviceStorageParams::TDeviceStorageCreateFdParams:
-    {
-      DeviceStorageCreateFdParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
-
-      r = new CreateFdEvent(this, dsf.forget());
-      break;
-    }
-
-    case DeviceStorageParams::TDeviceStorageGetParams:
-    {
-      DeviceStorageGetParams p = mParams;
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName(),
-                              p.rootDir(), p.relpath());
-      r = new ReadFileEvent(this, dsf.forget());
-      break;
-    }
-
-    case DeviceStorageParams::TDeviceStorageDeleteParams:
-    {
-      DeviceStorageDeleteParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
-      r = new DeleteFileEvent(this, dsf.forget());
-      break;
-    }
-
-    case DeviceStorageParams::TDeviceStorageFreeSpaceParams:
-    {
-      DeviceStorageFreeSpaceParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName());
-      r = new FreeSpaceFileEvent(this, dsf.forget());
-      break;
-    }
-
-    case DeviceStorageParams::TDeviceStorageUsedSpaceParams:
-    {
-      DeviceStorageUsedSpaceCache* usedSpaceCache
-        = DeviceStorageUsedSpaceCache::CreateOrGet();
-      MOZ_ASSERT(usedSpaceCache);
-
-      DeviceStorageUsedSpaceParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName());
-      usedSpaceCache->Dispatch(
-        MakeAndAddRef<UsedSpaceFileEvent>(this, dsf.forget()));
-      return;
-    }
-
-    case DeviceStorageParams::TDeviceStorageFormatParams:
-    {
-      DeviceStorageFormatParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName());
-      DebugOnly<nsresult> rv = NS_DispatchToMainThread(
-        new PostFormatResultEvent(this, dsf.forget()));
-      MOZ_ASSERT(NS_SUCCEEDED(rv));
-      return;
-    }
-
-    case DeviceStorageParams::TDeviceStorageMountParams:
-    {
-      DeviceStorageMountParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName());
-      DebugOnly<nsresult> rv = NS_DispatchToMainThread(
-        new PostMountResultEvent(this, dsf.forget()));
-      MOZ_ASSERT(NS_SUCCEEDED(rv));
-      return;
-    }
-
-    case DeviceStorageParams::TDeviceStorageUnmountParams:
-    {
-      DeviceStorageUnmountParams p = mParams;
-
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(p.type(), p.storageName());
-      DebugOnly<nsresult> rv = NS_DispatchToMainThread(
-        new PostUnmountResultEvent(this, dsf.forget()));
-      MOZ_ASSERT(NS_SUCCEEDED(rv));
-      return;
-    }
-
-    case DeviceStorageParams::TDeviceStorageEnumerationParams:
-    {
-      DeviceStorageEnumerationParams p = mParams;
-      RefPtr<DeviceStorageFile> dsf
-        = new DeviceStorageFile(p.type(), p.storageName(),
-                                p.rootdir(), NS_LITERAL_STRING(""));
-      r = new EnumerateFileEvent(this, dsf.forget(), p.since());
-      break;
-    }
-    default:
-    {
-      MOZ_CRASH("not reached");
-      return;
-    }
-  }
-
-  if (r) {
-    nsCOMPtr<nsIEventTarget> target =
-      do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
-    MOZ_ASSERT(target);
-    target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-  }
-}
-
-DeviceStorageRequestParent::~DeviceStorageRequestParent()
-{
-  MOZ_COUNT_DTOR(DeviceStorageRequestParent);
-}
-
-NS_IMPL_ADDREF(DeviceStorageRequestParent)
-NS_IMPL_RELEASE(DeviceStorageRequestParent)
-
-void
-DeviceStorageRequestParent::ActorDestroy(ActorDestroyReason)
-{
-  MutexAutoLock lock(mMutex);
-  mActorDestroyed = true;
-  for (auto& runnable : mRunnables) {
-    runnable->Cancel();
-  }
-  // Ensure we clear all references to the runnables so that there won't
-  // be leak due to cyclic reference. Note that it is safe to release
-  // the references here, since if a runnable is not cancelled yet, the
-  // corresponding thread should still hold a reference to it, and thus
-  // the runnable will end up being released in that thread, not here.
-  mRunnables.Clear();
-}
-
-DeviceStorageRequestParent::PostFreeSpaceResultEvent::PostFreeSpaceResultEvent(
-  DeviceStorageRequestParent* aParent,
-  uint64_t aFreeSpace)
-  : CancelableRunnable(aParent)
-  , mFreeSpace(aFreeSpace)
-{
-}
-
-DeviceStorageRequestParent::PostFreeSpaceResultEvent::
-  ~PostFreeSpaceResultEvent() {}
-
-nsresult
-DeviceStorageRequestParent::PostFreeSpaceResultEvent::CancelableRun() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  FreeSpaceStorageResponse response(mFreeSpace);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostUsedSpaceResultEvent::CancelableRun() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  UsedSpaceStorageResponse response(mUsedSpace);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-DeviceStorageRequestParent::PostErrorEvent::
-  PostErrorEvent(DeviceStorageRequestParent* aParent, const char* aError)
-  : CancelableRunnable(aParent)
-{
-  CopyASCIItoUTF16(aError, mError);
-}
-
-nsresult
-DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  ErrorResponse response(mError);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  SuccessResponse response;
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsString mime;
-  CopyASCIItoUTF16(mMimeType, mime);
-
-  nsString fullPath;
-  mFile->GetFullPath(fullPath);
-  RefPtr<BlobImpl> blob =
-    new BlobImplFile(fullPath, mime, mLength, mFile->mFile,
-                     mLastModificationDate);
-
-  ContentParent* cp = static_cast<ContentParent*>(mParent->Manager());
-  BlobParent* actor = cp->GetOrCreateActorForBlobImpl(blob);
-  if (!actor) {
-    ErrorResponse response(NS_LITERAL_STRING(POST_ERROR_EVENT_UNKNOWN));
-    Unused << mParent->Send__delete__(mParent, response);
-    return NS_OK;
-  }
-
-  BlobResponse response;
-  response.blobParent() = actor;
-
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  EnumerationResponse response(mStorageType, mRelPath, mPaths);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (!mFile->mFile) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-  bool check = false;
-  mFile->mFile->Exists(&check);
-  if (check) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
-  }
-
-  nsCOMPtr<nsIRunnable> r;
-  FileDescriptor fileDescriptor;
-  nsresult rv = mFile->CreateFileDescriptor(fileDescriptor);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("CreateFileDescriptor failed");
-    mFile->Dump("CreateFileDescriptor failed");
-    r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
-  }
-  else {
-    r = new PostFileDescriptorResultEvent(mParent, fileDescriptor);
-  }
-
-  return NS_DispatchToMainThread(r.forget());
-}
-
-nsresult
-DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (!mInputStream || !mFile->mFile) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  bool check = false;
-  nsresult rv;
-  mFile->mFile->Exists(&check);
-
-  if (mRequestType == DEVICE_STORAGE_REQUEST_CREATE) {
-    if (check) {
-      return NS_DispatchToMainThread(
-        new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
-    }
-    rv = mFile->Write(mInputStream);
-  } else if (mRequestType == DEVICE_STORAGE_REQUEST_APPEND) {
-    if (!check) {
-      return NS_DispatchToMainThread(
-        new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
-    }
-    rv = mFile->Append(mInputStream);
-  } else {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  nsCOMPtr<nsIRunnable> r;
-  if (NS_FAILED(rv)) {
-    r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
-  }
-  else {
-    r = new PostPathResultEvent(mParent, mFile->mPath);
-  }
-
-  return NS_DispatchToMainThread(r.forget());
-}
-
-nsresult
-DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  mFile->Remove();
-
-  if (!mFile->mFile) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-  nsCOMPtr<nsIRunnable> r;
-  bool check = false;
-  mFile->mFile->Exists(&check);
-  if (check) {
-    r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
-  }
-  else {
-    r = new PostPathResultEvent(mParent, mFile->mPath);
-  }
-
-  return NS_DispatchToMainThread(r.forget());
-}
-
-nsresult
-DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  int64_t freeSpace = 0;
-  if (mFile) {
-    mFile->GetStorageFreeSpace(&freeSpace);
-  }
-
-  return NS_DispatchToMainThread(
-    new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace)));
-}
-
-nsresult
-DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  uint64_t picturesUsage = 0, videosUsage = 0, musicUsage = 0, totalUsage = 0;
-  mFile->AccumDiskUsage(&picturesUsage, &videosUsage,
-                        &musicUsage, &totalUsage);
-  nsCOMPtr<nsIRunnable> r;
-  if (mFile->mStorageType.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
-    r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType,
-                                     picturesUsage);
-  }
-  else if (mFile->mStorageType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
-    r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, videosUsage);
-  }
-  else if (mFile->mStorageType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
-    r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, musicUsage);
-  } else {
-    r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage);
-  }
-  return NS_DispatchToMainThread(r.forget());
-}
-
-DeviceStorageRequestParent::ReadFileEvent::
-  ReadFileEvent(DeviceStorageRequestParent* aParent,
-                already_AddRefed<DeviceStorageFile>&& aFile)
-  : CancelableFileEvent(aParent, Move(aFile))
-{
-  nsCOMPtr<nsIMIMEService> mimeService
-    = do_GetService(NS_MIMESERVICE_CONTRACTID);
-  if (mimeService) {
-    nsresult rv = mimeService->GetTypeFromFile(mFile->mFile, mMimeType);
-    if (NS_FAILED(rv)) {
-      mMimeType.Truncate();
-    }
-  }
-}
-
-nsresult
-DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (!mFile->mFile) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-  bool check = false;
-  mFile->mFile->Exists(&check);
-
-  if (!check) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
-  }
-
-  int64_t fileSize;
-  nsresult rv = mFile->mFile->GetFileSize(&fileSize);
-  if (NS_FAILED(rv)) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  PRTime modDate;
-  rv = mFile->mFile->GetLastModifiedTime(&modDate);
-  if (NS_FAILED(rv)) {
-    return NS_DispatchToMainThread(
-      new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  return NS_DispatchToMainThread(
-    new PostBlobSuccessEvent(mParent, mFile.forget(),
-                             static_cast<uint64_t>(fileSize),
-                             mMimeType, modDate));
-}
-
-nsresult
-DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (mFile->mFile) {
-    bool check = false;
-    mFile->mFile->Exists(&check);
-    if (!check) {
-      return NS_DispatchToMainThread(
-        new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
-    }
-  }
-
-  nsTArray<RefPtr<DeviceStorageFile> > files;
-  mFile->CollectFiles(files, mSince);
-
-  InfallibleTArray<DeviceStorageFileValue> values;
-
-  uint32_t count = files.Length();
-  for (uint32_t i = 0; i < count; i++) {
-    DeviceStorageFileValue dsvf(files[i]->mStorageName, files[i]->mPath);
-    values.AppendElement(dsvf);
-  }
-
-  return NS_DispatchToMainThread(
-    new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
-                                    mFile->mRootDir, values));
-}
-
-nsresult
-DeviceStorageRequestParent::PostPathResultEvent::CancelableRun()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  SuccessResponse response;
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  FileDescriptorResponse response(mFileDescriptor);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsString state = NS_LITERAL_STRING("unavailable");
-  if (mFile) {
-    mFile->DoFormat(state);
-  }
-
-  FormatStorageResponse response(state);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostMountResultEvent::CancelableRun()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsString state = NS_LITERAL_STRING("unavailable");
-  if (mFile) {
-    mFile->DoMount(state);
-  }
-
-  MountStorageResponse response(state);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestParent::PostUnmountResultEvent::CancelableRun()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsString state = NS_LITERAL_STRING("unavailable");
-  if (mFile) {
-    mFile->DoUnmount(state);
-  }
-
-  UnmountStorageResponse response(state);
-  Unused << mParent->Send__delete__(mParent, response);
-  return NS_OK;
-}
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageRequestParent.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_devicestorage_DeviceStorageRequestParent_h
-#define mozilla_dom_devicestorage_DeviceStorageRequestParent_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/dom/devicestorage/PDeviceStorageRequestParent.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/ContentParent.h"
-
-#include "nsThreadUtils.h"
-#include "nsDeviceStorage.h"
-#include "nsTArray.h"
-
-namespace mozilla {
-namespace dom {
-namespace devicestorage {
-
-class DeviceStorageRequestParent : public PDeviceStorageRequestParent
-{
-public:
-  explicit DeviceStorageRequestParent(const DeviceStorageParams& aParams);
-
-  NS_IMETHOD_(MozExternalRefCountType) AddRef();
-  NS_IMETHOD_(MozExternalRefCountType) Release();
-
-  void Dispatch();
-
-  virtual void ActorDestroy(ActorDestroyReason);
-
-protected:
-  ~DeviceStorageRequestParent();
-
-private:
-  ThreadSafeAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-  DeviceStorageParams mParams;
-
-  // XXXkhuey name collision :(
-  class CancelableRunnable : public Runnable
-  {
-  public:
-    explicit CancelableRunnable(DeviceStorageRequestParent* aParent)
-      : mParent(aParent)
-    {
-      mCanceled = !(mParent->AddRunnable(this));
-    }
-
-    virtual ~CancelableRunnable() {
-    }
-
-    NS_IMETHOD Run() override {
-      nsresult rv = NS_OK;
-      if (!mCanceled) {
-        rv = CancelableRun();
-        mParent->RemoveRunnable(this);
-      }
-      return rv;
-    }
-
-    void Cancel() {
-      mCanceled = true;
-    }
-
-    virtual nsresult CancelableRun() = 0;
-
-  protected:
-    RefPtr<DeviceStorageRequestParent> mParent;
-  private:
-    bool mCanceled;
-  };
-
-  class CancelableFileEvent : public CancelableRunnable
-  {
-  protected:
-    CancelableFileEvent(DeviceStorageRequestParent* aParent,
-                        already_AddRefed<DeviceStorageFile>&& aFile)
-      : CancelableRunnable(aParent)
-      , mFile(Move(aFile)) {}
-
-    RefPtr<DeviceStorageFile> mFile;
-  };
-
-  class PostErrorEvent : public CancelableRunnable
-  {
-    public:
-      PostErrorEvent(DeviceStorageRequestParent* aParent, const char* aError);
-      virtual ~PostErrorEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      nsString mError;
-  };
-
-  class PostSuccessEvent : public CancelableRunnable
-  {
-    public:
-      explicit PostSuccessEvent(DeviceStorageRequestParent* aParent)
-        : CancelableRunnable(aParent) {}
-      virtual ~PostSuccessEvent() {}
-      virtual nsresult CancelableRun();
-  };
-
-  class PostBlobSuccessEvent : public CancelableFileEvent
-  {
-    public:
-      PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
-                           already_AddRefed<DeviceStorageFile>&& aFile,
-                           uint32_t aLength, nsACString& aMimeType,
-                           uint64_t aLastModifiedDate)
-        : CancelableFileEvent(aParent, Move(aFile))
-        , mLength(aLength)
-        , mLastModificationDate(aLastModifiedDate)
-        , mMimeType(aMimeType) {}
-      virtual ~PostBlobSuccessEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      uint32_t mLength;
-      uint64_t mLastModificationDate;
-      nsCString mMimeType;
-  };
-
-  class PostEnumerationSuccessEvent : public CancelableRunnable
-  {
-    public:
-      PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent,
-                                  const nsAString& aStorageType,
-                                  const nsAString& aRelPath,
-                                  InfallibleTArray<DeviceStorageFileValue>& aPaths)
-        : CancelableRunnable(aParent)
-        , mStorageType(aStorageType)
-        , mRelPath(aRelPath)
-        , mPaths(aPaths) {}
-      virtual ~PostEnumerationSuccessEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      const nsString mStorageType;
-      const nsString mRelPath;
-      InfallibleTArray<DeviceStorageFileValue> mPaths;
-  };
-
-  class CreateFdEvent : public CancelableFileEvent
-  {
-    public:
-      CreateFdEvent(DeviceStorageRequestParent* aParent,
-                    already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~CreateFdEvent() {}
-      virtual nsresult CancelableRun();
-  };
-
-  class WriteFileEvent : public CancelableFileEvent
-  {
-    public:
-      WriteFileEvent(DeviceStorageRequestParent* aParent,
-                     already_AddRefed<DeviceStorageFile>&& aFile,
-                     nsIInputStream* aInputStream, int32_t aRequestType)
-        : CancelableFileEvent(aParent, Move(aFile))
-        , mInputStream(aInputStream)
-        , mRequestType(aRequestType) {}
-      virtual ~WriteFileEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      nsCOMPtr<nsIInputStream> mInputStream;
-      int32_t mRequestType;
-  };
-
-  class DeleteFileEvent : public CancelableFileEvent
-  {
-    public:
-      DeleteFileEvent(DeviceStorageRequestParent* aParent,
-                      already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~DeleteFileEvent() {}
-      virtual nsresult CancelableRun();
-  };
-
-  class FreeSpaceFileEvent : public CancelableFileEvent
-  {
-    public:
-      FreeSpaceFileEvent(DeviceStorageRequestParent* aParent,
-                         already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~FreeSpaceFileEvent() {}
-      virtual nsresult CancelableRun();
-  };
-
-  class UsedSpaceFileEvent : public CancelableFileEvent
-  {
-    public:
-      UsedSpaceFileEvent(DeviceStorageRequestParent* aParent,
-                         already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~UsedSpaceFileEvent() {}
-      virtual nsresult CancelableRun();
-  };
-
-  class ReadFileEvent : public CancelableFileEvent
-  {
-    public:
-      ReadFileEvent(DeviceStorageRequestParent* aParent,
-                    already_AddRefed<DeviceStorageFile>&& aFile);
-      virtual ~ReadFileEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      nsCString mMimeType;
-  };
-
-  class EnumerateFileEvent : public CancelableFileEvent
-  {
-    public:
-      EnumerateFileEvent(DeviceStorageRequestParent* aParent,
-                         already_AddRefed<DeviceStorageFile>&& aFile,
-                         uint64_t aSince)
-        : CancelableFileEvent(aParent, Move(aFile))
-        , mSince(aSince) {}
-      virtual ~EnumerateFileEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      uint64_t mSince;
-  };
-
-  class PostPathResultEvent : public CancelableRunnable
-  {
-    public:
-      PostPathResultEvent(DeviceStorageRequestParent* aParent,
-                          const nsAString& aPath)
-        : CancelableRunnable(aParent)
-        , mPath(aPath) {}
-      virtual ~PostPathResultEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      nsString mPath;
-  };
-
-  class PostFileDescriptorResultEvent : public CancelableRunnable
-  {
-    public:
-      PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
-                                    const FileDescriptor& aFileDescriptor)
-        : CancelableRunnable(aParent)
-        , mFileDescriptor(aFileDescriptor) {}
-      virtual ~PostFileDescriptorResultEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      FileDescriptor mFileDescriptor;
-  };
-
- class PostFreeSpaceResultEvent : public CancelableRunnable
- {
-    public:
-      PostFreeSpaceResultEvent(DeviceStorageRequestParent* aParent,
-                               uint64_t aFreeSpace);
-      virtual ~PostFreeSpaceResultEvent();
-      virtual nsresult CancelableRun();
-    private:
-      uint64_t mFreeSpace;
- };
-
- class PostUsedSpaceResultEvent : public CancelableRunnable
- {
-    public:
-      PostUsedSpaceResultEvent(DeviceStorageRequestParent* aParent,
-                               const nsAString& aType,
-                               uint64_t aUsedSpace)
-        : CancelableRunnable(aParent)
-        , mType(aType)
-        , mUsedSpace(aUsedSpace) {}
-      virtual ~PostUsedSpaceResultEvent() {}
-      virtual nsresult CancelableRun();
-    private:
-      nsString mType;
-      uint64_t mUsedSpace;
- };
-
- class PostFormatResultEvent : public CancelableFileEvent
- {
-    public:
-      PostFormatResultEvent(DeviceStorageRequestParent* aParent,
-                            already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~PostFormatResultEvent() {}
-      virtual nsresult CancelableRun();
- };
-
- class PostMountResultEvent : public CancelableFileEvent
- {
-    public:
-      PostMountResultEvent(DeviceStorageRequestParent* aParent,
-                           already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~PostMountResultEvent() {}
-      virtual nsresult CancelableRun();
- };
-
- class PostUnmountResultEvent : public CancelableFileEvent
- {
-    public:
-      PostUnmountResultEvent(DeviceStorageRequestParent* aParent,
-                             already_AddRefed<DeviceStorageFile>&& aFile)
-        : CancelableFileEvent(aParent, Move(aFile)) {}
-      virtual ~PostUnmountResultEvent() {}
-      virtual nsresult CancelableRun();
- };
-
-protected:
-  bool AddRunnable(CancelableRunnable* aRunnable) {
-    MutexAutoLock lock(mMutex);
-    if (mActorDestroyed)
-      return false;
-
-    mRunnables.AppendElement(aRunnable);
-    return true;
-  }
-
-  void RemoveRunnable(CancelableRunnable* aRunnable) {
-    MutexAutoLock lock(mMutex);
-    mRunnables.RemoveElement(aRunnable);
-  }
-
-  Mutex mMutex;
-  bool mActorDestroyed;
-  nsTArray<RefPtr<CancelableRunnable> > mRunnables;
-};
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageStatics.cpp
+++ /dev/null
@@ -1,930 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DeviceStorageStatics.h"
-#include "mozilla/Preferences.h"
-#include "nsDeviceStorage.h"
-#include "nsIObserverService.h"
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsISupportsPrimitives.h"
-#include "nsPrintfCString.h"
-
-#ifdef MOZ_WIDGET_GONK
-#include "nsIVolume.h"
-#endif
-
-#ifdef MOZ_WIDGET_ANDROID
-#include "AndroidBridge.h"
-#endif
-
-namespace mozilla {
-namespace dom {
-namespace devicestorage {
-
-static const char* kPrefOverrideRootDir = "device.storage.overrideRootDir";
-static const char* kPrefTesting = "device.storage.testing";
-static const char* kPrefPromptTesting = "device.storage.prompt.testing";
-static const char* kPrefWritableName = "device.storage.writable.name";
-
-// file-watcher-notify comes from some process (but not the MTP Server)
-// to indicate that a file has changed. It eventually winds up in the
-// parent process, and then gets broadcast out to all child listeners
-// as a file-watcher-update and mtp-watcher-update.
-//
-// mtp-watcher-notify comes from the MTP Server whenever it detects a change
-// and this gets rebroadcast as file-watcher-update to the device storage
-// listeners.
-//
-// download-watcher-notify is treated similarly to file-watcher-notify,
-// and gets converted into file-watcher-update and mtp-watcher-update.
-//
-// We need to make sure that the MTP server doesn't get notified about
-// files which it told us it added, otherwise it confuses some clients
-// (like the Android-File-Transfer program which runs under OS X).
-
-static const char* kFileWatcherUpdate = "file-watcher-update";
-static const char* kMtpWatcherUpdate = "mtp-watcher-update";
-static const char* kDiskSpaceWatcher = "disk-space-watcher";
-static const char* kFileWatcherNotify = "file-watcher-notify";
-static const char* kMtpWatcherNotify = "mtp-watcher-notify";
-static const char* kDownloadWatcherNotify = "download-watcher-notify";
-
-StaticRefPtr<DeviceStorageStatics> DeviceStorageStatics::sInstance;
-StaticMutex DeviceStorageStatics::sMutex;
-
-NS_IMPL_ISUPPORTS(DeviceStorageStatics,
-                  nsIObserver)
-
-/* static */ void
-DeviceStorageStatics::Initialize()
-{
-  MOZ_ASSERT(!sInstance);
-  StaticMutexAutoLock lock(sMutex);
-  sInstance = new DeviceStorageStatics();
-  sInstance->Init();
-}
-
-/* static */ void
-DeviceStorageStatics::InitializeDirs()
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return;
-  }
-
-  /* The actual initialization can only happen on the main thread. This will
-     either happen when device storage is first used on the main thread, or
-     (in the future) when a worker is created. */
-  if (!sInstance->mInitialized && NS_IsMainThread()) {
-    sInstance->InitDirs();
-    sInstance->mInitialized = true;
-  }
-
-  MOZ_ASSERT(sInstance->mInitialized);
-}
-
-DeviceStorageStatics::DeviceStorageStatics()
-  : mInitialized(false)
-  , mPromptTesting(false)
-  , mLowDiskSpace(false)
-{
-  DS_LOG_INFO("");
-}
-
-DeviceStorageStatics::~DeviceStorageStatics()
-{
-  DS_LOG_INFO("");
-}
-
-void
-DeviceStorageStatics::Init()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  sMutex.AssertCurrentThreadOwns();
-  DS_LOG_INFO("");
-
-  Preferences::AddStrongObserver(this, kPrefTesting);
-  Preferences::AddStrongObserver(this, kPrefPromptTesting);
-  Preferences::AddStrongObserver(this, kPrefWritableName);
-
-  mWritableName = Preferences::GetString(kPrefWritableName);
-  mPromptTesting = Preferences::GetBool(kPrefPromptTesting, false);
-
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (obs) {
-    obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
-    obs->AddObserver(this, kFileWatcherNotify, false);
-    obs->AddObserver(this, kMtpWatcherNotify, false);
-    obs->AddObserver(this, kDownloadWatcherNotify, false);
-  }
-  DS_LOG_INFO("");
-}
-
-void
-DeviceStorageStatics::InitDirs()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  sMutex.AssertCurrentThreadOwns();
-  DS_LOG_INFO("");
-
-#if !defined(MOZ_WIDGET_GONK)
-  if (!XRE_IsParentProcess()) {
-    // For gonk, we have the parent process forward the directory information
-    // to the child using ContentParent::ForwardKnownInfo. On desktop, this
-    // winds up slowing down the startup (in particular ts_paint), so rather
-    // than penalize all e10s processes, we do a synchronous IPC call here,
-    // which only penalizes child processes which actually use DeviceStorage.
-
-    dom::ContentChild* child = dom::ContentChild::GetSingleton();
-    DeviceStorageLocationInfo locationInfo;
-    child->SendGetDeviceStorageLocations(&locationInfo);
-
-    NS_NewLocalFile(locationInfo.apps(),     true, getter_AddRefs(sInstance->mDirs[TYPE_APPS]));
-    NS_NewLocalFile(locationInfo.crashes(),  true, getter_AddRefs(sInstance->mDirs[TYPE_CRASHES]));
-    NS_NewLocalFile(locationInfo.pictures(), true, getter_AddRefs(sInstance->mDirs[TYPE_PICTURES]));
-    NS_NewLocalFile(locationInfo.videos(),   true, getter_AddRefs(sInstance->mDirs[TYPE_VIDEOS]));
-    NS_NewLocalFile(locationInfo.music(),    true, getter_AddRefs(sInstance->mDirs[TYPE_MUSIC]));
-    NS_NewLocalFile(locationInfo.sdcard(),   true, getter_AddRefs(sInstance->mDirs[TYPE_SDCARD]));
-
-    sInstance->mInitialized = true;
-    return;
-  }
-#endif
-
-  nsCOMPtr<nsIProperties> dirService
-    = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
-  MOZ_ASSERT(dirService);
-
-#if !defined(MOZ_WIDGET_GONK)
-
-// Keep MOZ_WIDGET_COCOA above XP_UNIX,
-// because both are defined in Darwin builds.
-#if defined (MOZ_WIDGET_COCOA)
-  dirService->Get(NS_OSX_PICTURE_DOCUMENTS_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_PICTURES]));
-  dirService->Get(NS_OSX_MOVIE_DOCUMENTS_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_VIDEOS]));
-  dirService->Get(NS_OSX_MUSIC_DOCUMENTS_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_MUSIC]));
-
-// Keep MOZ_WIDGET_ANDROID above XP_UNIX,
-// because both are defined in Android builds.
-#elif defined (MOZ_WIDGET_ANDROID)
-  nsAutoString path;
-  if (NS_SUCCEEDED(mozilla::AndroidBridge::GetExternalPublicDirectory(
-      NS_LITERAL_STRING(DEVICESTORAGE_PICTURES), path))) {
-    NS_NewLocalFile(path, /* aFollowLinks */ true,
-                    getter_AddRefs(mDirs[TYPE_PICTURES]));
-  }
-  if (NS_SUCCEEDED(mozilla::AndroidBridge::GetExternalPublicDirectory(
-      NS_LITERAL_STRING(DEVICESTORAGE_VIDEOS), path))) {
-    NS_NewLocalFile(path, /* aFollowLinks */ true,
-                    getter_AddRefs(mDirs[TYPE_VIDEOS]));
-  }
-  if (NS_SUCCEEDED(mozilla::AndroidBridge::GetExternalPublicDirectory(
-      NS_LITERAL_STRING(DEVICESTORAGE_MUSIC), path))) {
-    NS_NewLocalFile(path, /* aFollowLinks */ true,
-                    getter_AddRefs(mDirs[TYPE_MUSIC]));
-  }
-  if (NS_SUCCEEDED(mozilla::AndroidBridge::GetExternalPublicDirectory(
-      NS_LITERAL_STRING(DEVICESTORAGE_SDCARD), path))) {
-    NS_NewLocalFile(path, /* aFollowLinks */ true,
-                    getter_AddRefs(mDirs[TYPE_SDCARD]));
-  }
-
-#elif defined (XP_UNIX)
-  dirService->Get(NS_UNIX_XDG_PICTURES_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_PICTURES]));
-  dirService->Get(NS_UNIX_XDG_VIDEOS_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_VIDEOS]));
-  dirService->Get(NS_UNIX_XDG_MUSIC_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_MUSIC]));
-
-#elif defined (XP_WIN)
-  dirService->Get(NS_WIN_PICTURES_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_PICTURES]));
-  dirService->Get(NS_WIN_VIDEOS_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_VIDEOS]));
-  dirService->Get(NS_WIN_MUSIC_DIR,
-                  NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_MUSIC]));
-#endif
-
-#ifndef MOZ_WIDGET_ANDROID
-  // Eventually, on desktop, we want to do something smarter -- for example,
-  // detect when an sdcard is inserted, and use that instead of this.
-  dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_SDCARD]));
-  if (mDirs[TYPE_SDCARD]) {
-    mDirs[TYPE_SDCARD]->AppendRelativeNativePath(NS_LITERAL_CSTRING("fake-sdcard"));
-  }
-#endif // !MOZ_WIDGET_ANDROID
-
-  dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
-                  getter_AddRefs(mDirs[TYPE_APPS]));
-
-  if (mDirs[TYPE_APPS]) {
-    mDirs[TYPE_APPS]->AppendRelativeNativePath(NS_LITERAL_CSTRING("webapps"));
-  }
-#endif // !MOZ_WIDGET_GONK
-
-#ifdef MOZ_WIDGET_GONK
-  NS_NewLocalFile(NS_LITERAL_STRING("/data"),
-                  false,
-                  getter_AddRefs(mDirs[TYPE_APPS]));
-#endif
-
-  if (XRE_IsParentProcess()) {
-    NS_GetSpecialDirectory("UAppData", getter_AddRefs(mDirs[TYPE_CRASHES]));
-    if (mDirs[TYPE_CRASHES]) {
-      mDirs[TYPE_CRASHES]->Append(NS_LITERAL_STRING("Crash Reports"));
-    }
-  }
-#ifdef MOZ_WIDGET_GONK
-  // NS_GetSpecialDirectory("UAppData") fails in content processes because
-  // gAppData from toolkit/xre/nsAppRunner.cpp is not initialized.
-  else {
-    NS_NewLocalFile(NS_LITERAL_STRING("/data/b2g/mozilla/Crash Reports"),
-                                      false,
-                                      getter_AddRefs(mDirs[TYPE_CRASHES]));
-  }
-#endif
-
-  // Directories which don't depend on a volume should be calculated once
-  // here. Directories which depend on the root directory of a volume
-  // should be calculated in DeviceStorageFile::GetRootDirectoryForType.
-  Preferences::AddStrongObserver(this, kPrefOverrideRootDir);
-  ResetOverrideRootDir();
-}
-
-void
-DeviceStorageStatics::DumpDirs()
-{
-#ifdef DS_LOGGING
-  sMutex.AssertCurrentThreadOwns();
-
-  static const char* storageTypes[] = {
-    "app",
-    "crashes",
-    "pictures",
-    "videos",
-    "music",
-    "sdcard",
-    "override",
-    nullptr
-  };
-
-  const char* ptStr;
-  if (XRE_IsParentProcess()) {
-    ptStr = "parent";
-  } else {
-    ptStr = "child";
-  }
-
-  for (uint32_t i = 0; i < TYPE_COUNT; ++i) {
-    MOZ_ASSERT(storageTypes[i]);
-
-    nsString path;
-    if (mDirs[i]) {
-      mDirs[i]->GetPath(path);
-    }
-    DS_LOG_INFO("(%s) %s: '%s'",
-      ptStr, storageTypes[i], NS_LossyConvertUTF16toASCII(path).get());
-  }
-#endif
-}
-
-void
-DeviceStorageStatics::Shutdown()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  sMutex.AssertCurrentThreadOwns();
-  DS_LOG_INFO("");
-
-  Preferences::RemoveObserver(this, kPrefOverrideRootDir);
-  Preferences::RemoveObserver(this, kPrefTesting);
-  Preferences::RemoveObserver(this, kPrefPromptTesting);
-  Preferences::RemoveObserver(this, kPrefWritableName);
-}
-
-/* static */ void
-DeviceStorageStatics::GetDeviceStorageLocationsForIPC(
-  DeviceStorageLocationInfo* aLocationInfo)
-{
-  MOZ_ASSERT(XRE_IsParentProcess());
-  MOZ_ASSERT(NS_IsMainThread());
-
-  InitializeDirs();
-
-  GetDirPath(TYPE_APPS,     aLocationInfo->apps());
-  GetDirPath(TYPE_CRASHES,  aLocationInfo->crashes());
-  GetDirPath(TYPE_PICTURES, aLocationInfo->pictures());
-  GetDirPath(TYPE_VIDEOS,   aLocationInfo->videos());
-  GetDirPath(TYPE_MUSIC,    aLocationInfo->music());
-  GetDirPath(TYPE_SDCARD,   aLocationInfo->sdcard());
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetDir(DeviceStorageType aType)
-{
-  MOZ_ASSERT(aType < TYPE_COUNT);
-
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIFile> file;
-  switch (aType) {
-    case TYPE_APPS:
-    case TYPE_CRASHES:
-    case TYPE_OVERRIDE:
-      file = sInstance->mDirs[aType];
-      return file.forget();
-    default:
-      break;
-  }
-
-  // In testing, we default all device storage types to a temp directory.
-  // This is only initialized if the preference device.storage.testing
-  // was set to true, or if device.storage.overrideRootDir is set.
-  file = sInstance->mDirs[TYPE_OVERRIDE];
-  if (!file) {
-    file = sInstance->mDirs[aType];
-#ifdef MOZ_WIDGET_GONK
-    /* We should use volume mount points on B2G. */
-    MOZ_ASSERT(!file);
-#endif
-  }
-  return file.forget();
-}
-
-/* static */ void
-DeviceStorageStatics::GetDirPath(DeviceStorageType aType, nsString& aDirPath)
-{
-  aDirPath.Truncate();
-  nsCOMPtr<nsIFile> file = GetDir(aType);
-  if (file) {
-    file->GetPath(aDirPath);
-  }
-}
-
-/* static */ bool
-DeviceStorageStatics::HasOverrideRootDir()
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return false;
-  }
-  return sInstance->mDirs[TYPE_OVERRIDE];
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetAppsDir()
-{
-  return GetDir(TYPE_APPS);
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetCrashesDir()
-{
-  return GetDir(TYPE_CRASHES);
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetPicturesDir()
-{
-  return GetDir(TYPE_PICTURES);
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetVideosDir()
-{
-  return GetDir(TYPE_VIDEOS);
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetMusicDir()
-{
-  return GetDir(TYPE_MUSIC);
-}
-
-/* static */ already_AddRefed<nsIFile>
-DeviceStorageStatics::GetSdcardDir()
-{
-  return GetDir(TYPE_SDCARD);
-}
-
-/* static */ bool
-DeviceStorageStatics::IsPromptTesting()
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return false;
-  }
-  return sInstance->mPromptTesting;
-}
-
-/* static */ bool
-DeviceStorageStatics::LowDiskSpace()
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return false;
-  }
-  return sInstance->mLowDiskSpace;
-}
-
-/* static */ void
-DeviceStorageStatics::GetWritableName(nsString& aName)
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    aName.Truncate();
-    return;
-  }
-  aName = sInstance->mWritableName;
-}
-
-/* static */ void
-DeviceStorageStatics::SetWritableName(const nsAString& aName)
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (!NS_WARN_IF(!sInstance)) {
-    // Update inline although it will be updated again in case
-    // another thread comes in checking it before the update takes
-    sInstance->mWritableName = aName;
-  }
-
-  nsString name;
-  name.Assign(aName);
-  NS_DispatchToMainThread(NS_NewRunnableFunction([name] () -> void {
-    Preferences::SetString(kPrefWritableName, name);
-  }));
-}
-
-/* static */ void
-DeviceStorageStatics::AddListener(nsDOMDeviceStorage* aListener)
-{
-  DS_LOG_DEBUG("%p", aListener);
-
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return;
-  }
-
-  MOZ_ASSERT(sInstance->mInitialized);
-  if (sInstance->mListeners.IsEmpty()) {
-    NS_DispatchToMainThread(
-      NewRunnableMethod(sInstance.get(), &DeviceStorageStatics::Register));
-  }
-
-  RefPtr<ListenerWrapper> wrapper =
-    new ListenerWrapper(aListener);
-  sInstance->mListeners.AppendElement(wrapper.forget());
-}
-
-/* static */ void
-DeviceStorageStatics::RemoveListener(nsDOMDeviceStorage* aListener)
-{
-  DS_LOG_DEBUG("%p", aListener);
-
-  StaticMutexAutoLock lock(sMutex);
-  if (!sInstance) {
-    return;
-  }
-
-  bool removed = false;
-  uint32_t i = sInstance->mListeners.Length();
-  while (i > 0) {
-    --i;
-    if (sInstance->mListeners[i]->Equals(aListener)) {
-      sInstance->mListeners.RemoveElementAt(i);
-      removed = true;
-      break;
-    }
-  }
-
-  if (removed && sInstance->mListeners.IsEmpty()) {
-    NS_DispatchToMainThread(
-      NewRunnableMethod(sInstance.get(), &DeviceStorageStatics::Deregister));
-  }
-}
-
-void
-DeviceStorageStatics::Register()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  DS_LOG_INFO("");
-
-  StaticMutexAutoLock lock(sMutex);
-  if (NS_WARN_IF(!sInstance)) {
-    return;
-  }
-
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (obs) {
-    obs->AddObserver(this, kFileWatcherUpdate, false);
-    obs->AddObserver(this, kDiskSpaceWatcher, false);
-#ifdef MOZ_WIDGET_GONK
-    obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false);
-#endif
-  }
-}
-
-void
-DeviceStorageStatics::Deregister()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  DS_LOG_INFO("");
-
-  StaticMutexAutoLock lock(sMutex);
-  if (!sInstance) {
-    return;
-  }
-
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (obs) {
-    obs->RemoveObserver(this, kFileWatcherUpdate);
-    obs->RemoveObserver(this, kDiskSpaceWatcher);
-#ifdef MOZ_WIDGET_GONK
-    obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED);
-#endif
-  }
-}
-
-void
-DeviceStorageStatics::ResetOverrideRootDir()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  sMutex.AssertCurrentThreadOwns();
-  nsCOMPtr<nsIFile> f;
-  DS_LOG_INFO("");
-
-  // For users running on desktop, it's convenient to be able to override
-  // all of the directories to point to a single tree, much like what happens
-  // on a real device.
-  const nsAdoptingString& overrideRootDir =
-    mozilla::Preferences::GetString(kPrefOverrideRootDir);
-  if (overrideRootDir && !overrideRootDir.IsEmpty()) {
-    NS_NewLocalFile(overrideRootDir, false, getter_AddRefs(f));
-  }
-
-  if (!f && Preferences::GetBool(kPrefTesting, false)) {
-    DS_LOG_INFO("temp");
-    nsCOMPtr<nsIProperties> dirService
-      = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
-    MOZ_ASSERT(dirService);
-    dirService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
-    if (f) {
-      f->AppendRelativeNativePath(
-        NS_LITERAL_CSTRING("device-storage-testing"));
-    }
-  }
-
-  if (f) {
-    if (XRE_IsParentProcess()) {
-      // Only the parent process can create directories. In testing, because
-      // the preference is updated after startup, its entirely possible that
-      // the preference updated notification will be received by a child
-      // prior to the parent.
-      nsresult rv = f->Create(nsIFile::DIRECTORY_TYPE, 0777);
-      if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) {
-        nsString path;
-        f->GetPath(path);
-        nsPrintfCString msg("DeviceStorage: Unable to create directory '%s'",
-                            NS_LossyConvertUTF16toASCII(path).get());
-        NS_WARNING(msg.get());
-      }
-    }
-    f->Normalize();
-  }
-
-  mDirs[TYPE_OVERRIDE] = f.forget();
-  DumpDirs();
-}
-
-NS_IMETHODIMP
-DeviceStorageStatics::Observe(nsISupports* aSubject,
-                              const char* aTopic,
-                              const char16_t* aData)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
-    MOZ_ASSERT(aData);
-
-    StaticMutexAutoLock lock(sMutex);
-    if (NS_WARN_IF(!sInstance)) {
-      return NS_OK;
-    }
-
-    nsDependentString name(aData);
-    if (name.EqualsASCII(kPrefTesting) ||
-        name.EqualsASCII(kPrefOverrideRootDir)) {
-      ResetOverrideRootDir();
-    } else if(name.EqualsASCII(kPrefPromptTesting)) {
-      mPromptTesting = Preferences::GetBool(kPrefPromptTesting, false);
-      DS_LOG_INFO("prompt testing %d", mPromptTesting);
-    } else if(name.EqualsASCII(kPrefWritableName)) {
-      mWritableName = Preferences::GetString(kPrefWritableName);
-      uint32_t i = mListeners.Length();
-      DS_LOG_INFO("writable name '%s' (%u)",
-                  NS_LossyConvertUTF16toASCII(mWritableName).get(), i);
-      while (i > 0) {
-        --i;
-        mListeners[i]->OnWritableNameChanged();
-      }
-    }
-    return NS_OK;
-  }
-
-#ifdef MOZ_WIDGET_GONK
-  if (!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
-    nsCOMPtr<nsIVolume> volume = do_QueryInterface(aSubject);
-    if (NS_WARN_IF(!volume)) {
-      return NS_OK;
-    }
-
-    StaticMutexAutoLock lock(sMutex);
-    if (NS_WARN_IF(!sInstance)) {
-      return NS_OK;
-    }
-
-    uint32_t i = mListeners.Length();
-    DS_LOG_INFO("volume updated (%u)", i);
-    while (i > 0) {
-      --i;
-      mListeners[i]->OnVolumeStateChanged(volume);
-    }
-    return NS_OK;
-  }
-#endif
-
-  if (!strcmp(aTopic, kFileWatcherUpdate)) {
-    DeviceStorageFile* file = static_cast<DeviceStorageFile*>(aSubject);
-    if (NS_WARN_IF(!file)) {
-      return NS_OK;
-    }
-
-    StaticMutexAutoLock lock(sMutex);
-    if (NS_WARN_IF(!sInstance)) {
-      return NS_OK;
-    }
-
-    auto data = NS_ConvertUTF16toUTF8(aData);
-    uint32_t i = mListeners.Length();
-    DS_LOG_INFO("file updated (%u)", i);
-    while (i > 0) {
-      --i;
-      mListeners[i]->OnFileWatcherUpdate(data, file);
-    }
-    return NS_OK;
-  }
-
-  if (!strcmp(aTopic, kDiskSpaceWatcher)) {
-    StaticMutexAutoLock lock(sMutex);
-    if (NS_WARN_IF(!sInstance)) {
-      return NS_OK;
-    }
-
-    // 'disk-space-watcher' notifications are sent when there is a modification
-    // of a file in a specific location while a low device storage situation
-    // exists or after recovery of a low storage situation. For Firefox OS,
-    // these notifications are specific for apps storage.
-    if (!NS_strcmp(aData, u"full")) {
-      sInstance->mLowDiskSpace = true;
-    } else if (!NS_strcmp(aData, u"free")) {
-      sInstance->mLowDiskSpace = false;
-    } else {
-      return NS_OK;
-    }
-
-
-    uint32_t i = mListeners.Length();
-    DS_LOG_INFO("disk space %d (%u)", sInstance->mLowDiskSpace, i);
-    while (i > 0) {
-      --i;
-      mListeners[i]->OnDiskSpaceWatcher(sInstance->mLowDiskSpace);
-    }
-    return NS_OK;
-  }
-
-  if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
-    StaticMutexAutoLock lock(sMutex);
-    if (NS_WARN_IF(!sInstance)) {
-      return NS_OK;
-    }
-
-    Shutdown();
-    sInstance = nullptr;
-    return NS_OK;
-  }
-
-  /* Here we convert file-watcher-notify and download-watcher-notify observer
-     events to file-watcher-update events.  This is used to be able to
-     broadcast events from one child to another child in B2G.  (f.e., if one
-     child decides to add a file, we want to be able to able to send a onchange
-     notifications to every other child watching that device storage object).*/
-  RefPtr<DeviceStorageFile> dsf;
-  if (!strcmp(aTopic, kDownloadWatcherNotify)) {
-    // aSubject will be an nsISupportsString with the native path to the file
-    // in question.
-
-    nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(aSubject);
-    if (!supportsString) {
-      return NS_OK;
-    }
-    nsString path;
-    nsresult rv = supportsString->GetData(path);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return NS_OK;
-    }
-
-    // The downloader uses the sdcard storage type.
-    nsString volName;
-#ifdef MOZ_WIDGET_GONK
-    if (DeviceStorageTypeChecker::IsVolumeBased(NS_LITERAL_STRING(DEVICESTORAGE_SDCARD))) {
-      nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-      if (NS_WARN_IF(!vs)) {
-        return NS_OK;
-      }
-      nsCOMPtr<nsIVolume> vol;
-      rv = vs->GetVolumeByPath(path, getter_AddRefs(vol));
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return NS_OK;
-      }
-      rv = vol->GetName(volName);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return NS_OK;
-      }
-      nsString mountPoint;
-      rv = vol->GetMountPoint(mountPoint);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return NS_OK;
-      }
-      if (!Substring(path, 0, mountPoint.Length()).Equals(mountPoint)) {
-        return NS_OK;
-      }
-      path = Substring(path, mountPoint.Length() + 1);
-    }
-#endif
-    dsf = new DeviceStorageFile(NS_LITERAL_STRING(DEVICESTORAGE_SDCARD), volName, path);
-
-  } else if (!strcmp(aTopic, kFileWatcherNotify) ||
-             !strcmp(aTopic, kMtpWatcherNotify)) {
-    dsf = static_cast<DeviceStorageFile*>(aSubject);
-  } else {
-    DS_LOG_WARN("unhandled topic '%s'", aTopic);
-    return NS_OK;
-  }
-
-  if (NS_WARN_IF(!dsf || !dsf->mFile)) {
-    return NS_OK;
-  }
-
-  if (!XRE_IsParentProcess()) {
-    // Child process. Forward the notification to the parent.
-    ContentChild::GetSingleton()
-      ->SendFilePathUpdateNotify(dsf->mStorageType,
-                                 dsf->mStorageName,
-                                 dsf->mPath,
-                                 NS_ConvertUTF16toUTF8(aData));
-    return NS_OK;
-  }
-
-  // Multiple storage types may match the same files. So walk through each of
-  // the storage types, and if the extension matches, tell them about it.
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (DeviceStorageTypeChecker::IsSharedMediaRoot(dsf->mStorageType)) {
-    DeviceStorageTypeChecker* typeChecker
-      = DeviceStorageTypeChecker::CreateOrGet();
-    MOZ_ASSERT(typeChecker);
-
-    static const nsLiteralString kMediaTypes[] = {
-      NS_LITERAL_STRING(DEVICESTORAGE_SDCARD),
-      NS_LITERAL_STRING(DEVICESTORAGE_PICTURES),
-      NS_LITERAL_STRING(DEVICESTORAGE_VIDEOS),
-      NS_LITERAL_STRING(DEVICESTORAGE_MUSIC),
-    };
-
-    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(kMediaTypes); i++) {
-      RefPtr<DeviceStorageFile> dsf2;
-      if (typeChecker->Check(kMediaTypes[i], dsf->mPath)) {
-        if (dsf->mStorageType.Equals(kMediaTypes[i])) {
-          dsf2 = dsf;
-        } else {
-          dsf2 = new DeviceStorageFile(kMediaTypes[i],
-                                       dsf->mStorageName, dsf->mPath);
-        }
-        obs->NotifyObservers(dsf2, kFileWatcherUpdate, aData);
-      }
-    }
-  } else {
-    obs->NotifyObservers(dsf, kFileWatcherUpdate, aData);
-  }
-  if (strcmp(aTopic, kMtpWatcherNotify)) {
-    // Only send mtp-watcher-updates out if the MTP Server wasn't the one
-    // telling us about the change.
-    obs->NotifyObservers(dsf, kMtpWatcherUpdate, aData);
-  }
-  return NS_OK;
-}
-
-DeviceStorageStatics::ListenerWrapper::ListenerWrapper(nsDOMDeviceStorage* aListener)
-  : mListener(do_GetWeakReference(static_cast<DOMEventTargetHelper*>(aListener)))
-  , mOwningThread(NS_GetCurrentThread())
-{
-}
-
-DeviceStorageStatics::ListenerWrapper::~ListenerWrapper()
-{
-  // Even weak pointers are not thread safe
-  NS_ProxyRelease(mOwningThread, mListener.forget());
-}
-
-bool
-DeviceStorageStatics::ListenerWrapper::Equals(nsDOMDeviceStorage* aListener)
-{
-  bool current = false;
-  mOwningThread->IsOnCurrentThread(&current);
-  if (current) {
-    // It is only safe to acquire the reference on the owning thread
-    RefPtr<nsDOMDeviceStorage> listener = do_QueryReferent(mListener);
-    return listener.get() == aListener;
-  }
-  return false;
-}
-
-void
-DeviceStorageStatics::ListenerWrapper::OnFileWatcherUpdate(const nsCString& aData,
-                                                                 DeviceStorageFile* aFile)
-{
-  RefPtr<ListenerWrapper> self = this;
-  nsCString data = aData;
-  RefPtr<DeviceStorageFile> file = aFile;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, data, file] () -> void {
-    RefPtr<nsDOMDeviceStorage> listener = do_QueryReferent(self->mListener);
-    if (listener) {
-      listener->OnFileWatcherUpdate(data, file);
-    }
-  });
-  mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-}
-
-void
-DeviceStorageStatics::ListenerWrapper::OnDiskSpaceWatcher(bool aLowDiskSpace)
-{
-  RefPtr<ListenerWrapper> self = this;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, aLowDiskSpace] () -> void {
-    RefPtr<nsDOMDeviceStorage> listener = do_QueryReferent(self->mListener);
-    if (listener) {
-      listener->OnDiskSpaceWatcher(aLowDiskSpace);
-    }
-  });
-  mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-}
-
-void
-DeviceStorageStatics::ListenerWrapper::OnWritableNameChanged()
-{
-  RefPtr<ListenerWrapper> self = this;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void {
-    RefPtr<nsDOMDeviceStorage> listener = do_QueryReferent(self->mListener);
-    if (listener) {
-      listener->OnWritableNameChanged();
-    }
-  });
-  mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-}
-
-#ifdef MOZ_WIDGET_GONK
-void
-DeviceStorageStatics::ListenerWrapper::OnVolumeStateChanged(nsIVolume* aVolume)
-{
-  RefPtr<ListenerWrapper> self = this;
-  nsCOMPtr<nsIVolume> volume = aVolume;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, volume] () -> void {
-    RefPtr<nsDOMDeviceStorage> listener = do_QueryReferent(self->mListener);
-    if (listener) {
-      listener->OnVolumeStateChanged(volume);
-    }
-  });
-  mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-}
-#endif
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/devicestorage/DeviceStorageStatics.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_devicestorage_DeviceStorageStatics_h
-#define mozilla_dom_devicestorage_DeviceStorageStatics_h
-
-#include "mozilla/Mutex.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/StaticMutex.h"
-#include "mozilla/StaticPtr.h"
-#include "nsArrayUtils.h"
-
-class nsString;
-class nsDOMDeviceStorage;
-class DeviceStorageFile;
-#ifdef MOZ_WIDGET_GONK
-class nsIVolume;
-#endif
-
-namespace mozilla {
-namespace dom {
-namespace devicestorage {
-
-class DeviceStorageStatics final : public nsIObserver
-{
-public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-
-  static void Initialize();
-  static void InitializeDirs();
-  static void AddListener(nsDOMDeviceStorage* aListener);
-  static void RemoveListener(nsDOMDeviceStorage* aListener);
-
-  static bool LowDiskSpace();
-  static bool IsPromptTesting();
-  static void GetWritableName(nsString& aName);
-  static void SetWritableName(const nsAString& aName);
-
-  static void GetDeviceStorageLocationsForIPC(DeviceStorageLocationInfo* aLocationInfo);
-
-  static bool HasOverrideRootDir();
-  static already_AddRefed<nsIFile> GetAppsDir();
-  static already_AddRefed<nsIFile> GetCrashesDir();
-  static already_AddRefed<nsIFile> GetPicturesDir();
-  static already_AddRefed<nsIFile> GetVideosDir();
-  static already_AddRefed<nsIFile> GetMusicDir();
-  static already_AddRefed<nsIFile> GetSdcardDir();
-
-private:
-  enum DeviceStorageType {
-    TYPE_APPS,
-    TYPE_CRASHES,
-    TYPE_PICTURES,
-    TYPE_VIDEOS,
-    TYPE_MUSIC,
-    TYPE_SDCARD,
-    TYPE_OVERRIDE,
-    TYPE_COUNT
-  };
-
-  static already_AddRefed<nsIFile> GetDir(DeviceStorageType aType);
-  static void GetDirPath(DeviceStorageType aType, nsString& aString);
-
-  DeviceStorageStatics();
-  virtual ~DeviceStorageStatics();
-
-  void Init();
-  void InitDirs();
-  void DumpDirs();
-  void Shutdown();
-  void Register();
-  void Deregister();
-  void ResetOverrideRootDir();
-
-  class ListenerWrapper final {
-  public:
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ListenerWrapper)
-
-    explicit ListenerWrapper(nsDOMDeviceStorage* aListener);
-    bool Equals(nsDOMDeviceStorage* aListener);
-    void OnFileWatcherUpdate(const nsCString& aData, DeviceStorageFile* aFile);
-    void OnDiskSpaceWatcher(bool aLowDiskSpace);
-    void OnWritableNameChanged();
-#ifdef MOZ_WIDGET_GONK
-    void OnVolumeStateChanged(nsIVolume* aVolume);
-#endif
-
-  private:
-    virtual ~ListenerWrapper();
-
-    nsWeakPtr mListener;
-    nsCOMPtr<nsIThread> mOwningThread;
-  };
-
-  nsTArray<RefPtr<ListenerWrapper> > mListeners;
-  nsCOMPtr<nsIFile> mDirs[TYPE_COUNT];
-
-  bool mInitialized;
-  bool mPromptTesting;
-  bool mLowDiskSpace;
-  nsString mWritableName;
-
-  static StaticRefPtr<DeviceStorageStatics> sInstance;
-  static StaticMutex sMutex;
-};
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/dom/devicestorage/PDeviceStorageRequest.ipdl
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-include protocol PBlob;
-include protocol PContent;
-
-namespace mozilla {
-namespace dom {
-namespace devicestorage {
-
-
-struct ErrorResponse
-{
-  nsString error;
-};
-
-struct SuccessResponse
-{
-};
-
-struct FileDescriptorResponse
-{
-  FileDescriptor fileDescriptor;
-};
-
-struct BlobResponse
-{
-  PBlob blob;
-};
-
-struct DeviceStorageFileValue
-{
-  nsString storageName;
-  nsString name;
-};
-
-struct EnumerationResponse
-{
-  nsString type;
-  nsString rootdir;
-  DeviceStorageFileValue[] paths;
-};
-
-struct FreeSpaceStorageResponse
-{
-  uint64_t freeBytes;
-};
-
-struct UsedSpaceStorageResponse
-{
-  uint64_t usedBytes;
-};
-
-struct FormatStorageResponse
-{
-  nsString mountState;
-};
-
-struct MountStorageResponse
-{
-  nsString storageStatus;
-};
-
-struct UnmountStorageResponse
-{
-  nsString storageStatus;
-};
-
-union DeviceStorageResponseValue
-{
-  ErrorResponse;
-  SuccessResponse;
-  FileDescriptorResponse;
-  BlobResponse;
-  EnumerationResponse;
-  FreeSpaceStorageResponse;
-  UsedSpaceStorageResponse;
-  FormatStorageResponse;
-  MountStorageResponse;
-  UnmountStorageResponse;
-};
-
-sync protocol PDeviceStorageRequest {
-    manager PContent;
-child:
-    async __delete__(DeviceStorageResponseValue response);
-};
-
-} // namespace devicestorage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/devicestorage/moz.build
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
-    'DeviceStorage.h',
-    'DeviceStorageFileDescriptor.h',
-    'nsDeviceStorage.h',
-]
-
-EXPORTS.mozilla.dom.devicestorage += [
-    'DeviceStorageRequestChild.h',
-    'DeviceStorageRequestParent.h',
-    'DeviceStorageStatics.h',
-]
-
-UNIFIED_SOURCES += [
-    'DeviceStorageRequestChild.cpp',
-    'DeviceStorageRequestParent.cpp',
-    'DeviceStorageStatics.cpp',
-    'nsDeviceStorage.cpp',
-]
-
-IPDL_SOURCES += [
-    'PDeviceStorageRequest.ipdl',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
-    '/dom/base',
-    '/dom/ipc',
-]
-
-MOCHITEST_MANIFESTS += [
-    'test/mochitest.ini',
-]
-MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
deleted file mode 100644
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ /dev/null
@@ -1,4137 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsDeviceStorage.h"
-
-#include "mozilla/Attributes.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/DeviceStorageBinding.h"
-#include "mozilla/dom/DeviceStorageFileSystem.h"
-#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
-#include "mozilla/dom/Directory.h"
-#include "mozilla/dom/FileSystemUtils.h"
-#include "mozilla/dom/ipc/BlobChild.h"
-#include "mozilla/dom/PBrowserChild.h"
-#include "mozilla/dom/PermissionMessageUtils.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/EventDispatcher.h"
-#include "mozilla/EventListenerManager.h"
-#include "mozilla/LazyIdleThread.h"
-#include "mozilla/Scoped.h"
-#include "mozilla/Services.h"
-#include "mozilla/ipc/BackgroundUtils.h" // for PrincipalInfoToPrincipal
-
-#include "nsArrayUtils.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsGlobalWindow.h"
-#include "nsServiceManagerUtils.h"
-#include "nsIFile.h"
-#include "nsIDirectoryEnumerator.h"
-#include "nsNetUtil.h"
-#include "nsIOutputStream.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsIPrincipal.h"
-#include "nsJSUtils.h"
-#include "nsContentUtils.h"
-#include "nsXULAppAPI.h"
-#include "DeviceStorageFileDescriptor.h"
-#include "DeviceStorageRequestChild.h"
-#include "DeviceStorageStatics.h"
-#include "nsCRT.h"
-#include "nsIObserverService.h"
-#include "nsIMIMEService.h"
-#include "nsCExternalHandlerService.h"
-#include "nsIPermissionManager.h"
-#include "nsIStringBundle.h"
-#include "nsISupportsPrimitives.h"
-#include "nsIDocument.h"
-#include <algorithm>
-#include "private/pprio.h"
-#include "nsContentPermissionHelper.h"
-
-#include "mozilla/dom/DeviceStorageBinding.h"
-
-// Microsoft's API Name hackery sucks
-#undef CreateEvent
-
-#ifdef MOZ_WIDGET_GONK
-#include "nsIVolume.h"
-#include "nsIVolumeService.h"
-#endif
-
-#define DEVICESTORAGE_PROPERTIES \
-  "chrome://global/content/devicestorage.properties"
-#define DEFAULT_THREAD_TIMEOUT_MS 30000
-#define STORAGE_CHANGE_EVENT "change"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-using namespace mozilla::dom::devicestorage;
-using namespace mozilla::ipc;
-
-namespace mozilla
-{
-  MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, PR_Close);
-} // namespace mozilla
-
-namespace {
-
-void
-NormalizeFilePath(nsAString& aPath)
-{
-#if defined(XP_WIN)
-  char16_t* cur = aPath.BeginWriting();
-  char16_t* end = aPath.EndWriting();
-  for (; cur < end; ++cur) {
-    if (char16_t('\\') == *cur) {
-      *cur = FILESYSTEM_DOM_PATH_SEPARATOR_CHAR;
-    }
-  }
-#endif
-}
-
-bool
-TokenizerIgnoreNothing(char16_t /* aChar */)
-{
-  return false;
-}
-
-} // anonymous namespace
-
-StaticAutoPtr<DeviceStorageUsedSpaceCache>
-  DeviceStorageUsedSpaceCache::sDeviceStorageUsedSpaceCache;
-
-DeviceStorageUsedSpaceCache::DeviceStorageUsedSpaceCache()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  mIOThread = new LazyIdleThread(
-    DEFAULT_THREAD_TIMEOUT_MS,
-    NS_LITERAL_CSTRING("DeviceStorageUsedSpaceCache I/O"));
-
-}
-
-DeviceStorageUsedSpaceCache::~DeviceStorageUsedSpaceCache()
-{
-}
-
-DeviceStorageUsedSpaceCache*
-DeviceStorageUsedSpaceCache::CreateOrGet()
-{
-  if (sDeviceStorageUsedSpaceCache) {
-    return sDeviceStorageUsedSpaceCache;
-  }
-
-  MOZ_ASSERT(NS_IsMainThread());
-
-  sDeviceStorageUsedSpaceCache = new DeviceStorageUsedSpaceCache();
-  ClearOnShutdown(&sDeviceStorageUsedSpaceCache);
-  return sDeviceStorageUsedSpaceCache;
-}
-
-already_AddRefed<DeviceStorageUsedSpaceCache::CacheEntry>
-DeviceStorageUsedSpaceCache::GetCacheEntry(const nsAString& aStorageName)
-{
-  nsTArray<RefPtr<CacheEntry>>::size_type numEntries = mCacheEntries.Length();
-  nsTArray<RefPtr<CacheEntry>>::index_type i;
-  for (i = 0; i < numEntries; i++) {
-    RefPtr<CacheEntry>& cacheEntry = mCacheEntries[i];
-    if (cacheEntry->mStorageName.Equals(aStorageName)) {
-      RefPtr<CacheEntry> addRefedCacheEntry = cacheEntry;
-      return addRefedCacheEntry.forget();
-    }
-  }
-  return nullptr;
-}
-
-static int64_t
-GetFreeBytes(const nsAString& aStorageName)
-{
-  // This function makes the assumption that the various types
-  // are all stored on the same filesystem. So we use pictures.
-
-  RefPtr<DeviceStorageFile> dsf(new DeviceStorageFile(NS_LITERAL_STRING(DEVICESTORAGE_PICTURES),
-                                                        aStorageName));
-  int64_t freeBytes = 0;
-  dsf->GetStorageFreeSpace(&freeBytes);
-  return freeBytes;
-}
-
-nsresult
-DeviceStorageUsedSpaceCache::AccumUsedSizes(const nsAString& aStorageName,
-                                            uint64_t* aPicturesSoFar,
-                                            uint64_t* aVideosSoFar,
-                                            uint64_t* aMusicSoFar,
-                                            uint64_t* aTotalSoFar)
-{
-  RefPtr<CacheEntry> cacheEntry = GetCacheEntry(aStorageName);
-  if (!cacheEntry || cacheEntry->mDirty) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-  int64_t freeBytes = GetFreeBytes(cacheEntry->mStorageName);
-  if (freeBytes != cacheEntry->mFreeBytes) {
-    // Free space changed, so our cached results are no longer valid.
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  *aPicturesSoFar += cacheEntry->mPicturesUsedSize;
-  *aVideosSoFar += cacheEntry->mVideosUsedSize;
-  *aMusicSoFar += cacheEntry->mMusicUsedSize;
-  *aTotalSoFar += cacheEntry->mTotalUsedSize;
-
-  return NS_OK;
-}
-
-void
-DeviceStorageUsedSpaceCache::SetUsedSizes(const nsAString& aStorageName,
-                                          uint64_t aPictureSize,
-                                          uint64_t aVideosSize,
-                                          uint64_t aMusicSize,
-                                          uint64_t aTotalUsedSize)
-{
-  RefPtr<CacheEntry> cacheEntry = GetCacheEntry(aStorageName);
-  if (!cacheEntry) {
-    cacheEntry = new CacheEntry;
-    cacheEntry->mStorageName = aStorageName;
-    mCacheEntries.AppendElement(cacheEntry);
-  }
-  cacheEntry->mFreeBytes = GetFreeBytes(cacheEntry->mStorageName);
-
-  cacheEntry->mPicturesUsedSize = aPictureSize;
-  cacheEntry->mVideosUsedSize = aVideosSize;
-  cacheEntry->mMusicUsedSize = aMusicSize;
-  cacheEntry->mTotalUsedSize = aTotalUsedSize;
-  cacheEntry->mDirty = false;
-}
-
-StaticAutoPtr<DeviceStorageTypeChecker>
-  DeviceStorageTypeChecker::sDeviceStorageTypeChecker;
-
-DeviceStorageTypeChecker::DeviceStorageTypeChecker()
-{
-}
-
-DeviceStorageTypeChecker::~DeviceStorageTypeChecker()
-{
-}
-
-DeviceStorageTypeChecker*
-DeviceStorageTypeChecker::CreateOrGet()
-{
-  if (sDeviceStorageTypeChecker) {
-    return sDeviceStorageTypeChecker;
-  }
-
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIStringBundleService> stringService
-    = mozilla::services::GetStringBundleService();
-  if (!stringService) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIStringBundle> filterBundle;
-  if (NS_FAILED(stringService->CreateBundle(DEVICESTORAGE_PROPERTIES,
-                                            getter_AddRefs(filterBundle)))) {
-    return nullptr;
-  }
-
-  DeviceStorageTypeChecker* result = new DeviceStorageTypeChecker();
-  result->InitFromBundle(filterBundle);
-
-  sDeviceStorageTypeChecker = result;
-  ClearOnShutdown(&sDeviceStorageTypeChecker);
-  return result;
-}
-
-void
-DeviceStorageTypeChecker::InitFromBundle(nsIStringBundle* aBundle)
-{
-  aBundle->GetStringFromName(
-    NS_ConvertASCIItoUTF16(DEVICESTORAGE_PICTURES).get(),
-    getter_Copies(mPicturesExtensions));
-  aBundle->GetStringFromName(
-    NS_ConvertASCIItoUTF16(DEVICESTORAGE_MUSIC).get(),
-    getter_Copies(mMusicExtensions));
-  aBundle->GetStringFromName(
-    NS_ConvertASCIItoUTF16(DEVICESTORAGE_VIDEOS).get(),
-    getter_Copies(mVideosExtensions));
-}
-
-
-bool
-DeviceStorageTypeChecker::Check(const nsAString& aType, BlobImpl* aBlob)
-{
-  MOZ_ASSERT(aBlob);
-
-  nsString mimeType;
-  aBlob->GetType(mimeType);
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
-    return StringBeginsWith(mimeType, NS_LITERAL_STRING("image/"));
-  }
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
-    return StringBeginsWith(mimeType, NS_LITERAL_STRING("video/"));
-  }
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
-    return StringBeginsWith(mimeType, NS_LITERAL_STRING("audio/"));
-  }
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_APPS) ||
-      aType.EqualsLiteral(DEVICESTORAGE_SDCARD) ||
-      aType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
-    // Apps, crashes and sdcard have no restriction on mime types
-    return true;
-  }
-
-  return false;
-}
-
-bool
-DeviceStorageTypeChecker::Check(const nsAString& aType, nsIFile* aFile)
-{
-  if (!aFile) {
-    return false;
-  }
-
-  nsString path;
-  aFile->GetPath(path);
-
-  return Check(aType, path);
-}
-
-bool
-DeviceStorageTypeChecker::Check(const nsAString& aType, const nsString& aPath)
-{
-  if (aType.EqualsLiteral(DEVICESTORAGE_APPS) ||
-      aType.EqualsLiteral(DEVICESTORAGE_SDCARD) ||
-      aType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
-    // Apps, crashes and sdcard have no restrictions on what file extensions used.
-    return true;
-  }
-
-  int32_t dotIdx = aPath.RFindChar(char16_t('.'));
-  if (dotIdx == kNotFound) {
-    return false;
-  }
-
-  nsAutoString extensionMatch;
-  extensionMatch.Assign('*');
-  extensionMatch.Append(Substring(aPath, dotIdx));
-  extensionMatch.Append(';');
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
-    return CaseInsensitiveFindInReadable(extensionMatch, mPicturesExtensions);
-  }
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
-    return CaseInsensitiveFindInReadable(extensionMatch, mVideosExtensions);
-  }
-
-  if (aType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
-    return CaseInsensitiveFindInReadable(extensionMatch, mMusicExtensions);
-  }
-
-  return false;
-}
-
-void
-DeviceStorageTypeChecker::GetTypeFromFile(nsIFile* aFile, nsAString& aType)
-{
-  MOZ_ASSERT(aFile);
-
-  nsString path;
-  aFile->GetPath(path);
-
-  GetTypeFromFileName(path, aType);
-}
-
-void
-DeviceStorageTypeChecker::GetTypeFromFileName(const nsAString& aFileName,
-                                              nsAString& aType)
-{
-  aType.AssignLiteral(DEVICESTORAGE_SDCARD);
-
-  nsString fileName(aFileName);
-  int32_t dotIdx = fileName.RFindChar(char16_t('.'));
-  if (dotIdx == kNotFound) {
-    return;
-  }
-
-  nsAutoString extensionMatch;
-  extensionMatch.Assign('*');
-  extensionMatch.Append(Substring(aFileName, dotIdx));
-  extensionMatch.Append(';');
-
-  if (CaseInsensitiveFindInReadable(extensionMatch, mPicturesExtensions)) {
-    aType.AssignLiteral(DEVICESTORAGE_PICTURES);
-  }
-  else if (CaseInsensitiveFindInReadable(extensionMatch, mVideosExtensions)) {
-    aType.AssignLiteral(DEVICESTORAGE_VIDEOS);
-  }
-  else if (CaseInsensitiveFindInReadable(extensionMatch, mMusicExtensions)) {
-    aType.AssignLiteral(DEVICESTORAGE_MUSIC);
-  }
-}
-
-nsresult
-DeviceStorageTypeChecker::GetPermissionForType(const nsAString& aType,
-                                               nsACString& aPermissionResult)
-{
-  if (!aType.EqualsLiteral(DEVICESTORAGE_PICTURES) &&
-      !aType.EqualsLiteral(DEVICESTORAGE_VIDEOS) &&
-      !aType.EqualsLiteral(DEVICESTORAGE_MUSIC) &&
-      !aType.EqualsLiteral(DEVICESTORAGE_APPS) &&
-      !aType.EqualsLiteral(DEVICESTORAGE_SDCARD) &&
-      !aType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
-    // unknown type
-    return NS_ERROR_FAILURE;
-  }
-
-  aPermissionResult.AssignLiteral("device-storage:");
-  aPermissionResult.Append(NS_ConvertUTF16toUTF8(aType));
-  return NS_OK;
-}
-
-size_t
-DeviceStorageTypeChecker::GetAccessIndexForRequest(
-  const DeviceStorageRequestType aRequestType)
-{
-  switch(aRequestType) {
-    case DEVICE_STORAGE_REQUEST_READ:
-    case DEVICE_STORAGE_REQUEST_WATCH:
-    case DEVICE_STORAGE_REQUEST_FREE_SPACE:
-    case DEVICE_STORAGE_REQUEST_USED_SPACE:
-    case DEVICE_STORAGE_REQUEST_AVAILABLE:
-    case DEVICE_STORAGE_REQUEST_STATUS:
-    case DEVICE_STORAGE_REQUEST_CURSOR:
-      return DEVICE_STORAGE_ACCESS_READ;
-    case DEVICE_STORAGE_REQUEST_WRITE:
-    case DEVICE_STORAGE_REQUEST_APPEND:
-    case DEVICE_STORAGE_REQUEST_DELETE:
-    case DEVICE_STORAGE_REQUEST_FORMAT:
-    case DEVICE_STORAGE_REQUEST_MOUNT:
-    case DEVICE_STORAGE_REQUEST_UNMOUNT:
-      return DEVICE_STORAGE_ACCESS_WRITE;
-    case DEVICE_STORAGE_REQUEST_CREATE:
-    case DEVICE_STORAGE_REQUEST_CREATEFD:
-      return DEVICE_STORAGE_ACCESS_CREATE;
-    default:
-      return DEVICE_STORAGE_ACCESS_UNDEFINED;
-  }
-}
-
-nsresult
-DeviceStorageTypeChecker::GetAccessForRequest(
-  const DeviceStorageRequestType aRequestType, nsACString& aAccessResult)
-{
-  size_t access = GetAccessIndexForRequest(aRequestType);
-  return GetAccessForIndex(access, aAccessResult);
-}
-
-nsresult
-DeviceStorageTypeChecker::GetAccessForIndex(
-  size_t aAccessIndex, nsACString& aAccessResult)
-{
-  static const char *names[] = { "read", "write", "create", "undefined" };
-  MOZ_ASSERT(aAccessIndex < MOZ_ARRAY_LENGTH(names));
-  aAccessResult.AssignASCII(names[aAccessIndex]);
-  return NS_OK;
-}
-
-static bool IsMediaType(const nsAString& aType)
-{
-  return aType.EqualsLiteral(DEVICESTORAGE_PICTURES) ||
-         aType.EqualsLiteral(DEVICESTORAGE_VIDEOS) ||
-         aType.EqualsLiteral(DEVICESTORAGE_MUSIC) ||
-         aType.EqualsLiteral(DEVICESTORAGE_SDCARD);
-}
-
-//static
-bool
-DeviceStorageTypeChecker::IsVolumeBased(const nsAString& aType)
-{
-#ifdef MOZ_WIDGET_GONK
-  // The apps and crashes aren't stored in the same place as the media, so
-  // we only ever return a single apps object, and not an array
-  // with one per volume (as is the case for the remaining
-  // storage types).
-  return IsMediaType(aType);
-#else
-  return false;
-#endif
-}
-
-//static
-bool
-DeviceStorageTypeChecker::IsSharedMediaRoot(const nsAString& aType)
-{
-  // This function determines if aType shares a root directory with the
-  // other media types (so only applies to music, videos, pictures and sdcard).
-#ifdef MOZ_WIDGET_GONK
-  return IsMediaType(aType);
-#else
-  // For desktop, if the directories have been overridden, then they share
-  // a common root.
-  return IsMediaType(aType) && DeviceStorageStatics::HasOverrideRootDir();
-#endif
-}
-
-class IOEventComplete : public Runnable
-{
-public:
-  IOEventComplete(DeviceStorageFile *aFile, const char *aType)
-    : mFile(aFile)
-    , mType(aType)
-  {
-  }
-
-  ~IOEventComplete() {}
-
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    nsString data;
-    CopyASCIItoUTF16(mType, data);
-    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-
-    obs->NotifyObservers(mFile, "file-watcher-notify", data.get());
-
-    DeviceStorageUsedSpaceCache* usedSpaceCache
-      = DeviceStorageUsedSpaceCache::CreateOrGet();
-    MOZ_ASSERT(usedSpaceCache);
-    usedSpaceCache->Invalidate(mFile->mStorageName);
-    return NS_OK;
-  }
-
-private:
-  RefPtr<DeviceStorageFile> mFile;
-  nsCString mType;
-};
-
-DeviceStorageFile::DeviceStorageFile(const nsAString& aStorageType,
-                                     const nsAString& aStorageName,
-                                     const nsAString& aRootDir,
-                                     const nsAString& aPath)
-  : mStorageType(aStorageType)
-  , mStorageName(aStorageName)
-  , mRootDir(aRootDir)
-  , mPath(aPath)
-  , mEditable(false)
-  , mLength(UINT64_MAX)
-  , mLastModifiedDate(UINT64_MAX)
-{
-  Init();
-  AppendRelativePath(mRootDir);
-  if (!mPath.EqualsLiteral("")) {
-    AppendRelativePath(mPath);
-  }
-
-  NormalizeFilePath(mPath);
-}
-
-DeviceStorageFile::DeviceStorageFile(const nsAString& aStorageType,
-                                     const nsAString& aStorageName,
-                                     const nsAString& aPath)
-  : mStorageType(aStorageType)
-  , mStorageName(aStorageName)
-  , mPath(aPath)
-  , mEditable(false)
-  , mLength(UINT64_MAX)
-  , mLastModifiedDate(UINT64_MAX)
-{
-  Init();
-  AppendRelativePath(aPath);
-  NormalizeFilePath(mPath);
-}
-
-DeviceStorageFile::DeviceStorageFile(const nsAString& aStorageType,
-                                     const nsAString& aStorageName)
-  : mStorageType(aStorageType)
-  , mStorageName(aStorageName)
-  , mEditable(false)
-  , mLength(UINT64_MAX)
-  , mLastModifiedDate(UINT64_MAX)
-{
-  Init();
-}
-
-void
-DeviceStorageFile::Dump(const char* label)
-{
-  nsString path;
-  if (mFile) {
-    mFile->GetPath(path);
-  } else {
-    path = NS_LITERAL_STRING("(null)");
-  }
-  const char* ptStr;
-  if (XRE_IsParentProcess()) {
-    ptStr = "parent";
-  } else {
-    ptStr = "child";
-  }
-
-  printf_stderr("DSF (%s) %s: mStorageType '%s' mStorageName '%s' "
-                "mRootDir '%s' mPath '%s' mFile->GetPath '%s'\n",
-                ptStr, label,
-                NS_LossyConvertUTF16toASCII(mStorageType).get(),
-                NS_LossyConvertUTF16toASCII(mStorageName).get(),
-                NS_LossyConvertUTF16toASCII(mRootDir).get(),
-                NS_LossyConvertUTF16toASCII(mPath).get(),
-                NS_LossyConvertUTF16toASCII(path).get());
-}
-
-void
-DeviceStorageFile::Init()
-{
-  DeviceStorageFile::GetRootDirectoryForType(mStorageType,
-                                             mStorageName,
-                                             getter_AddRefs(mFile));
-
-  DebugOnly<DeviceStorageTypeChecker*> typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  MOZ_ASSERT(typeChecker);
-
-  DS_LOG_INFO("type '%s' name '%s' root '%s' path '%s'",
-              NS_LossyConvertUTF16toASCII(mStorageType).get(),
-              NS_LossyConvertUTF16toASCII(mStorageName).get(),
-              NS_LossyConvertUTF16toASCII(mRootDir).get(),
-              NS_LossyConvertUTF16toASCII(mPath).get());
-}
-
-void
-DeviceStorageFile::GetFullPath(nsAString &aFullPath)
-{
-  aFullPath.Truncate();
-  if (!mStorageName.EqualsLiteral("")) {
-    aFullPath.Append('/');
-    aFullPath.Append(mStorageName);
-    aFullPath.Append('/');
-  }
-  if (!mRootDir.EqualsLiteral("")) {
-    aFullPath.Append(mRootDir);
-    aFullPath.Append('/');
-  }
-  aFullPath.Append(mPath);
-}
-
-
-// Directories which don't depend on a volume should be calculated once
-// in DeviceStorageStatics::Initialize. Directories which depend on the
-// root directory of a volume should be calculated in this method.
-void
-DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType,
-                                           const nsAString& aStorageName,
-                                           nsIFile** aFile)
-{
-  nsCOMPtr<nsIFile> f;
-  *aFile = nullptr;
-
-  DeviceStorageStatics::InitializeDirs();
-
-#ifdef MOZ_WIDGET_GONK
-  nsresult rv;
-  nsString volMountPoint;
-  if (DeviceStorageTypeChecker::IsVolumeBased(aStorageType)) {
-    nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-    NS_ENSURE_TRUE_VOID(vs);
-    nsCOMPtr<nsIVolume> vol;
-    rv = vs->GetVolumeByName(aStorageName, getter_AddRefs(vol));
-    if (NS_FAILED(rv)) {
-      printf_stderr("##### DeviceStorage: GetVolumeByName('%s') failed\n",
-                    NS_LossyConvertUTF16toASCII(aStorageName).get());
-    }
-    NS_ENSURE_SUCCESS_VOID(rv);
-    vol->GetMountPoint(volMountPoint);
-  }
-#endif
-
-  if (aStorageType.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
-    f = DeviceStorageStatics::GetPicturesDir();
-  } else if (aStorageType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
-    f = DeviceStorageStatics::GetVideosDir();
-  } else if (aStorageType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
-    f = DeviceStorageStatics::GetMusicDir();
-  } else if (aStorageType.EqualsLiteral(DEVICESTORAGE_APPS)) {
-    f = DeviceStorageStatics::GetAppsDir();
-  } else if (aStorageType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
-    f = DeviceStorageStatics::GetCrashesDir();
-  } else if (aStorageType.EqualsLiteral(DEVICESTORAGE_SDCARD)) {
-    f = DeviceStorageStatics::GetSdcardDir();
-  } else {
-    printf_stderr("##### DeviceStorage: Unrecognized StorageType: '%s'\n",
-                  NS_LossyConvertUTF16toASCII(aStorageType).get());
-    return;
-  }
-
-#ifdef MOZ_WIDGET_GONK
-  /* For volume based storage types, we will only have a file already
-     if the override root directory option is in effect. */
-  if (!f && !volMountPoint.IsEmpty()) {
-    rv = NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f));
-    if (NS_FAILED(rv)) {
-      printf_stderr("##### DeviceStorage: NS_NewLocalFile failed StorageType: '%s' path '%s'\n",
-                    NS_LossyConvertUTF16toASCII(volMountPoint).get(),
-                    NS_LossyConvertUTF16toASCII(aStorageType).get());
-    }
-  }
-#endif
-
-  if (f) {
-    f->Clone(aFile);
-  } else {
-    // This should never happen unless something is severely wrong. So
-    // scream a little.
-    printf_stderr("##### GetRootDirectoryForType('%s', '%s') failed #####",
-                  NS_LossyConvertUTF16toASCII(aStorageType).get(),
-                  NS_LossyConvertUTF16toASCII(aStorageName).get());
-  }
-}
-
-//static
-already_AddRefed<DeviceStorageFile>
-DeviceStorageFile::CreateUnique(nsAString& aFileName,
-                                uint32_t aFileType,
-                                uint32_t aFileAttributes)
-{
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  MOZ_ASSERT(typeChecker);
-
-  nsString storageType;
-  typeChecker->GetTypeFromFileName(aFileName, storageType);
-
-  nsString storageName;
-  nsString storagePath;
-  if (!nsDOMDeviceStorage::ParseFullPath(aFileName, storageName, storagePath)) {
-    return nullptr;
-  }
-  if (storageName.IsEmpty()) {
-    nsDOMDeviceStorage::GetDefaultStorageName(storageType, storageName);
-  }
-  return CreateUnique(storageType, storageName, storagePath,
-                      aFileType, aFileAttributes);
-}
-
-//static
-already_AddRefed<DeviceStorageFile>
-DeviceStorageFile::CreateUnique(const nsAString& aStorageType,
-                                const nsAString& aStorageName,
-                                nsAString& aFileName,
-                                uint32_t aFileType,
-                                uint32_t aFileAttributes)
-{
-  RefPtr<DeviceStorageFile> dsf =
-    new DeviceStorageFile(aStorageType, aStorageName, aFileName);
-  if (!dsf->mFile) {
-    return nullptr;
-  }
-
-  nsresult rv = dsf->mFile->CreateUnique(aFileType, aFileAttributes);
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  // CreateUnique may cause the filename to change. So we need to update mPath
-  // to reflect that.
-  nsString leafName;
-  dsf->mFile->GetLeafName(leafName);
-
-  int32_t lastSlashIndex = dsf->mPath.RFindChar('/');
-  if (lastSlashIndex == kNotFound) {
-    dsf->mPath.Assign(leafName);
-  } else {
-    // Include the last '/'
-    dsf->mPath = Substring(dsf->mPath, 0, lastSlashIndex + 1);
-    dsf->mPath.Append(leafName);
-  }
-
-  return dsf.forget();
-}
-
-void
-DeviceStorageFile::SetPath(const nsAString& aPath) {
-  mPath.Assign(aPath);
-  NormalizeFilePath(mPath);
-}
-
-void
-DeviceStorageFile::SetEditable(bool aEditable) {
-  mEditable = aEditable;
-}
-
-// we want to make sure that the names of file can't reach
-// outside of the type of storage the user asked for.
-bool
-DeviceStorageFile::IsSafePath() const
-{
-  return ValidateAndSplitPath(mRootDir) && ValidateAndSplitPath(mPath);
-}
-
-bool
-DeviceStorageFile::ValidateAndSplitPath(const nsAString& aPath,
-                                        nsTArray<nsString>* aParts) const
-{
-  nsAString::const_iterator start, end;
-  aPath.BeginReading(start);
-  aPath.EndReading(end);
-
-  // if the path is a '~' or starts with '~/', return false.
-  NS_NAMED_LITERAL_STRING(tilde, "~");
-  NS_NAMED_LITERAL_STRING(tildeSlash, "~/");
-  if (aPath.Equals(tilde) ||
-      StringBeginsWith(aPath, tildeSlash)) {
-    NS_WARNING("Path name starts with tilde!");
-    return false;
-  }
-
-  NS_NAMED_LITERAL_STRING(kCurrentDir, ".");
-  NS_NAMED_LITERAL_STRING(kParentDir, "..");
-
-  // Split path and check each path component.
-  nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing>
-    tokenizer(aPath, FILESYSTEM_DOM_PATH_SEPARATOR_CHAR);
-
-  while (tokenizer.hasMoreTokens()) {
-    nsDependentSubstring pathComponent = tokenizer.nextToken();
-    // The path containing empty components, such as "foo//bar", is invalid.
-    // We don't allow paths, such as "../foo", "foo/./bar" and "foo/../bar",
-    // to walk up the directory.
-    if (pathComponent.IsEmpty() ||
-        pathComponent.Equals(kCurrentDir) ||
-        pathComponent.Equals(kParentDir)) {
-      return false;
-    }
-
-    if (aParts) {
-      aParts->AppendElement(pathComponent);
-    }
-  }
-  return true;
-}
-
-void
-DeviceStorageFile::AppendRelativePath(const nsAString& aPath)
-{
-  if (!mFile) {
-    return;
-  }
-
-  nsTArray<nsString> parts;
-
-  if (!ValidateAndSplitPath(aPath, &parts)) {
-    // All of the APIs (in the child) do checks to verify that the path is
-    // valid and return PERMISSION_DENIED if a non-safe path is entered.
-    // This check is done in the parent and prevents a compromised
-    // child from bypassing the check. It shouldn't be possible for this
-    // code path to be taken with a non-compromised child.
-    NS_WARNING("Unsafe path detected - ignoring");
-    NS_WARNING(NS_LossyConvertUTF16toASCII(aPath).get());
-    return;
-  }
-
-  for (uint32_t i = 0; i < parts.Length(); ++i) {
-    nsresult rv = mFile->AppendRelativePath(parts[i]);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-  }
-}
-
-nsresult
-DeviceStorageFile::CreateFileDescriptor(FileDescriptor& aFileDescriptor)
-{
-  if (!mFile) {
-    return NS_ERROR_FAILURE;
-  }
-  ScopedPRFileDesc fd;
-  nsresult rv = mFile->OpenNSPRFileDesc(PR_RDWR | PR_CREATE_FILE,
-                                        0660, &fd.rwget());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // NOTE: The FileDescriptor::PlatformHandleType constructor returns a dup of
-  //       the file descriptor, so we don't need the original fd after this.
-  //       Our scoped file descriptor will automatically close fd.
-  aFileDescriptor = FileDescriptor(
-    FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(fd)));
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageFile::Write(nsIInputStream* aInputStream)
-{
-  if (!aInputStream || !mFile) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIOutputStream> outputStream;
-  NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile);
-
-  if (!outputStream) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return Append(aInputStream, outputStream);
-}
-
-nsresult
-DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
-{
-  if (!mFile) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIOutputStream> outputStream;
-  NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile);
-
-  if (!outputStream) {
-    return NS_ERROR_FAILURE;
-  }
-
-  uint32_t wrote;
-  outputStream->Write((char*) aBits.Elements(), aBits.Length(), &wrote);
-  outputStream->Close();
-
-  rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (aBits.Length() != wrote) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageFile::Append(nsIInputStream* aInputStream)
-{
-  if (!aInputStream || !mFile) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIOutputStream> outputStream;
-  NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile, PR_WRONLY | PR_CREATE_FILE | PR_APPEND, -1, 0);
-
-  if (!outputStream) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return Append(aInputStream, outputStream);
-}
-
-
-nsresult
-DeviceStorageFile::Append(nsIInputStream* aInputStream, nsIOutputStream* aOutputStream)
-{
-  uint64_t bufSize = 0;
-  aInputStream->Available(&bufSize);
-
-  nsCOMPtr<nsIOutputStream> bufferedOutputStream;
-  nsresult rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
-                                  aOutputStream,
-                                  4096*4);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  while (bufSize) {
-    uint32_t wrote;
-    rv = bufferedOutputStream->WriteFrom(
-      aInputStream,
-        static_cast<uint32_t>(std::min<uint64_t>(bufSize, UINT32_MAX)),
-        &wrote);
-    if (NS_FAILED(rv)) {
-      break;
-    }
-    bufSize -= wrote;
-  }
-
-  rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  bufferedOutputStream->Close();
-  aOutputStream->Close();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageFile::Remove()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (!mFile) {
-    return NS_ERROR_FAILURE;
-  }
-
-  bool check;
-  nsresult rv = mFile->Exists(&check);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (!check) {
-    return NS_OK;
-  }
-
-  rv = mFile->Remove(true);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_DispatchToMainThread(new IOEventComplete(this, "deleted"));
-}
-
-nsresult
-DeviceStorageFile::CalculateMimeType()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!mFile) {
-    return NS_ERROR_FAILURE;
-  }
-  nsAutoCString mimeType;
-  nsCOMPtr<nsIMIMEService> mimeService =
-    do_GetService(NS_MIMESERVICE_CONTRACTID);
-  if (mimeService) {
-    nsresult rv = mimeService->GetTypeFromFile(mFile, mimeType);
-    if (NS_FAILED(rv)) {
-      mimeType.Truncate();
-      return rv;
-    }
-  }
-
-  mMimeType = NS_ConvertUTF8toUTF16(mimeType);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageFile::CalculateSizeAndModifiedDate()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (!mFile) {
-    return NS_ERROR_FAILURE;
-  }
-
-  int64_t fileSize;
-  nsresult rv = mFile->GetFileSize(&fileSize);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mLength = fileSize;
-
-  PRTime modDate;
-  rv = mFile->GetLastModifiedTime(&modDate);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mLastModifiedDate = modDate;
-  return NS_OK;
-}
-
-void
-DeviceStorageFile::CollectFiles(nsTArray<RefPtr<DeviceStorageFile> > &aFiles,
-                                PRTime aSince)
-{
-  if (!mFile) {
-    return;
-  }
-  nsString fullRootPath;
-  mFile->GetPath(fullRootPath);
-  collectFilesInternal(aFiles, aSince, fullRootPath);
-}
-
-void
-DeviceStorageFile::collectFilesInternal(
-  nsTArray<RefPtr<DeviceStorageFile> > &aFiles,
-  PRTime aSince,
-  nsAString& aRootPath)
-{
-  if (!mFile || !IsAvailable()) {
-    return;
-  }
-
-  nsCOMPtr<nsISimpleEnumerator> e;
-  mFile->GetDirectoryEntries(getter_AddRefs(e));
-
-  if (!e) {
-    return;
-  }
-
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  MOZ_ASSERT(typeChecker);
-
-  nsCOMPtr<nsIDirectoryEnumerator> files = do_QueryInterface(e);
-  nsCOMPtr<nsIFile> f;
-
-  while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(f))) && f) {
-
-    bool isFile;
-    f->IsFile(&isFile);
-
-    if (isFile) {
-      PRTime msecs;
-      f->GetLastModifiedTime(&msecs);
-
-      if (msecs < aSince) {
-        continue;
-      }
-    }
-
-    bool isDir;
-    f->IsDirectory(&isDir);
-
-    nsString fullpath;
-    nsresult rv = f->GetPath(fullpath);
-    if (NS_FAILED(rv)) {
-      continue;
-    }
-
-    if (isFile && !typeChecker->Check(mStorageType, fullpath)) {
-      continue;
-    }
-
-    if (!StringBeginsWith(fullpath, aRootPath)) {
-      NS_ERROR("collectFiles returned a path that does not belong!");
-      continue;
-    }
-
-    nsAString::size_type len = aRootPath.Length() + 1; // +1 for the trailing /
-    nsDependentSubstring newPath = Substring(fullpath, len);
-
-    if (isDir) {
-      DeviceStorageFile dsf(mStorageType, mStorageName, mRootDir, newPath);
-      dsf.collectFilesInternal(aFiles, aSince, aRootPath);
-    } else if (isFile) {
-      RefPtr<DeviceStorageFile> dsf =
-        new DeviceStorageFile(mStorageType, mStorageName, mRootDir, newPath);
-      dsf->CalculateSizeAndModifiedDate();
-      aFiles.AppendElement(dsf);
-    }
-  }
-}
-
-void
-DeviceStorageFile::AccumDiskUsage(uint64_t* aPicturesSoFar,
-                                  uint64_t* aVideosSoFar,
-                                  uint64_t* aMusicSoFar,
-                                  uint64_t* aTotalSoFar)
-{
-  if (!IsAvailable()) {
-    return;
-  }
-
-  uint64_t pictureUsage = 0, videoUsage = 0, musicUsage = 0, totalUsage = 0;
-
-  if (DeviceStorageTypeChecker::IsVolumeBased(mStorageType)) {
-    DeviceStorageUsedSpaceCache* usedSpaceCache =
-      DeviceStorageUsedSpaceCache::CreateOrGet();
-    MOZ_ASSERT(usedSpaceCache);
-    nsresult rv = usedSpaceCache->AccumUsedSizes(mStorageName,
-                                                 aPicturesSoFar, aVideosSoFar,
-                                                 aMusicSoFar, aTotalSoFar);
-    if (NS_SUCCEEDED(rv)) {
-      return;
-    }
-    AccumDirectoryUsage(mFile, &pictureUsage, &videoUsage,
-                        &musicUsage, &totalUsage);
-    usedSpaceCache->SetUsedSizes(mStorageName, pictureUsage, videoUsage,
-                                 musicUsage, totalUsage);
-  } else {
-    AccumDirectoryUsage(mFile, &pictureUsage, &videoUsage,
-                        &musicUsage, &totalUsage);
-  }
-
-  *aPicturesSoFar += pictureUsage;
-  *aVideosSoFar += videoUsage;
-  *aMusicSoFar += musicUsage;
-  *aTotalSoFar += totalUsage;
-}
-
-void
-DeviceStorageFile::AccumDirectoryUsage(nsIFile* aFile,
-                                       uint64_t* aPicturesSoFar,
-                                       uint64_t* aVideosSoFar,
-                                       uint64_t* aMusicSoFar,
-                                       uint64_t* aTotalSoFar)
-{
-  if (!aFile) {
-    return;
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsISimpleEnumerator> e;
-  rv = aFile->GetDirectoryEntries(getter_AddRefs(e));
-
-  if (NS_FAILED(rv) || !e) {
-    return;
-  }
-
-  nsCOMPtr<nsIDirectoryEnumerator> files = do_QueryInterface(e);
-  MOZ_ASSERT(files);
-
-  nsCOMPtr<nsIFile> f;
-  while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(f))) && f) {
-    bool isDir;
-    rv = f->IsDirectory(&isDir);
-    if (NS_FAILED(rv)) {
-      continue;
-    }
-
-    bool isFile;
-    rv = f->IsFile(&isFile);
-    if (NS_FAILED(rv)) {
-      continue;
-    }
-
-    bool isLink;
-    rv = f->IsSymlink(&isLink);
-    if (NS_FAILED(rv)) {
-      continue;
-    }
-
-    if (isLink) {
-      // for now, lets just totally ignore symlinks.
-      NS_WARNING("DirectoryDiskUsage ignores symlinks");
-    } else if (isDir) {
-      AccumDirectoryUsage(f, aPicturesSoFar, aVideosSoFar,
-                          aMusicSoFar, aTotalSoFar);
-    } else if (isFile) {
-
-      int64_t size;
-      rv = f->GetFileSize(&size);
-      if (NS_FAILED(rv)) {
-        continue;
-      }
-      DeviceStorageTypeChecker* typeChecker
-        = DeviceStorageTypeChecker::CreateOrGet();
-      MOZ_ASSERT(typeChecker);
-      nsString type;
-      typeChecker->GetTypeFromFile(f, type);
-
-      if (type.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
-        *aPicturesSoFar += size;
-      }
-      else if (type.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
-        *aVideosSoFar += size;
-      }
-      else if (type.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
-        *aMusicSoFar += size;
-      }
-      *aTotalSoFar += size;
-    }
-  }
-}
-
-void
-DeviceStorageFile::GetStorageFreeSpace(int64_t* aSoFar)
-{
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker) {
-    return;
-  }
-  if (!mFile || !IsAvailable()) {
-    return;
-  }
-
-  int64_t storageAvail = 0;
-  nsresult rv = mFile->GetDiskSpaceAvailable(&storageAvail);
-  if (NS_SUCCEEDED(rv)) {
-    *aSoFar += storageAvail;
-  }
-}
-
-bool
-DeviceStorageFile::IsAvailable()
-{
-  nsString status;
-  GetStatus(status);
-  return status.EqualsLiteral("available");
-}
-
-void
-DeviceStorageFile::DoFormat(nsAString& aStatus)
-{
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker || !mFile) {
-    return;
-  }
-  if (!typeChecker->IsVolumeBased(mStorageType)) {
-    aStatus.AssignLiteral("notVolume");
-    return;
-  }
-#ifdef MOZ_WIDGET_GONK
-  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(vs);
-
-  nsCOMPtr<nsIVolume> vol;
-  nsresult rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (!vol) {
-    return;
-  }
-
-  vol->Format();
-
-  aStatus.AssignLiteral("formatting");
-#endif
-  return;
-}
-
-void
-DeviceStorageFile::DoMount(nsAString& aStatus)
-{
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker || !mFile) {
-    return;
-  }
-  if (!typeChecker->IsVolumeBased(mStorageType)) {
-    aStatus.AssignLiteral("notVolume");
-    return;
-  }
-#ifdef MOZ_WIDGET_GONK
-  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(vs);
-
-  nsCOMPtr<nsIVolume> vol;
-  nsresult rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (!vol) {
-    return;
-  }
-
-  vol->Mount();
-
-  aStatus.AssignLiteral("mounting");
-#endif
-  return;
-}
-
-void
-DeviceStorageFile::DoUnmount(nsAString& aStatus)
-{
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker || !mFile) {
-    return;
-  }
-  if (!typeChecker->IsVolumeBased(mStorageType)) {
-    aStatus.AssignLiteral("notVolume");
-    return;
-  }
-#ifdef MOZ_WIDGET_GONK
-  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(vs);
-
-  nsCOMPtr<nsIVolume> vol;
-  nsresult rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (!vol) {
-    return;
-  }
-
-  vol->Unmount();
-
-  aStatus.AssignLiteral("unmounting");
-#endif
-  return;
-}
-
-void
-DeviceStorageFile::GetStatus(nsAString& aStatus)
-{
-  aStatus.AssignLiteral("unavailable");
-
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker || !mFile) {
-    return;
-  }
-  if (!typeChecker->IsVolumeBased(mStorageType)) {
-    aStatus.AssignLiteral("available");
-    return;
-  }
-
-#ifdef MOZ_WIDGET_GONK
-  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(vs);
-
-  nsCOMPtr<nsIVolume> vol;
-  nsresult rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (!vol) {
-    return;
-  }
-  bool isMediaPresent;
-  rv = vol->GetIsMediaPresent(&isMediaPresent);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (!isMediaPresent) {
-    return;
-  }
-  bool isSharing;
-  rv = vol->GetIsSharing(&isSharing);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (isSharing) {
-    aStatus.AssignLiteral("shared");
-    return;
-  }
-  bool isFormatting;
-  rv = vol->GetIsFormatting(&isFormatting);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (isFormatting) {
-    aStatus.AssignLiteral("unavailable");
-    return;
-  }
-  bool isUnmounting;
-  rv = vol->GetIsUnmounting(&isUnmounting);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (isUnmounting) {
-    aStatus.AssignLiteral("unavailable");
-    return;
-  }
-  int32_t volState;
-  rv = vol->GetState(&volState);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (volState == nsIVolume::STATE_MOUNTED) {
-    aStatus.AssignLiteral("available");
-  }
-#endif
-}
-
-void
-DeviceStorageFile::GetStorageStatus(nsAString& aStatus)
-{
-  aStatus.AssignLiteral("undefined");
-
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker || !mFile) {
-    return;
-  }
-  if (!typeChecker->IsVolumeBased(mStorageType)) {
-    aStatus.AssignLiteral("available");
-    return;
-  }
-
-#ifdef MOZ_WIDGET_GONK
-  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(vs);
-
-  nsCOMPtr<nsIVolume> vol;
-  nsresult rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
-  NS_ENSURE_SUCCESS_VOID(rv);
-  if (!vol) {
-    return;
-  }
-
-  int32_t volState;
-  rv = vol->GetState(&volState);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  aStatus.AssignASCII(mozilla::system::NS_VolumeStateStr(volState));
-#endif
-}
-
-NS_IMPL_ISUPPORTS0(DeviceStorageFile)
-
-void
-nsDOMDeviceStorage::SetRootDirectoryForType(const nsAString& aStorageType,
-                                            const nsAString& aStorageName)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIFile> f;
-  DeviceStorageFile::GetRootDirectoryForType(aStorageType,
-                                             aStorageName,
-                                             getter_AddRefs(f));
-  mRootDirectory = f;
-  mStorageType = aStorageType;
-  mStorageName = aStorageName;
-}
-
-nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIGlobalObject* aGlobal,
-                                                   DeviceStorageCursorRequest* aRequest)
-  : DOMCursor(aGlobal, nullptr)
-  , mOkToCallContinue(false)
-  , mRequest(aRequest)
-{
-}
-
-nsDOMDeviceStorageCursor::~nsDOMDeviceStorageCursor()
-{
-}
-
-void
-nsDOMDeviceStorageCursor::FireSuccess(JS::Handle<JS::Value> aResult)
-{
-  mOkToCallContinue = true;
-  DOMCursor::FireSuccess(aResult);
-}
-
-void
-nsDOMDeviceStorageCursor::FireDone()
-{
-  mRequest = nullptr;
-  DOMCursor::FireDone();
-}
-
-void
-nsDOMDeviceStorageCursor::FireError(const nsString& aReason)
-{
-  mOkToCallContinue = false;
-  mRequest = nullptr;
-
-  if (!mResult.isUndefined()) {
-    // If we previously succeeded, we cannot fail without
-    // clearing the last result.
-    mResult.setUndefined();
-    mDone = false;
-  }
-
-  DOMCursor::FireError(aReason);
-}
-
-void
-nsDOMDeviceStorageCursor::Continue(ErrorResult& aRv)
-{
-  if (!mOkToCallContinue || !mRequest) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return;
-  }
-
-  if (!mResult.isUndefined()) {
-    // We call onsuccess multiple times. Clear the last
-    // result.
-    mResult.setUndefined();
-    mDone = false;
-  }
-
-  mOkToCallContinue = false;
-  aRv = mRequest->Continue();
-}
-
-DeviceStorageRequest::DeviceStorageRequest()
-  : mId(DeviceStorageRequestManager::INVALID_ID)
-  , mAccess(DEVICE_STORAGE_ACCESS_UNDEFINED)
-  , mSendToParent(true)
-  , mUseMainThread(false)
-  , mUseStreamTransport(false)
-  , mCheckFile(false)
-  , mCheckBlob(false)
-  , mMultipleResolve(false)
-  , mPermissionCached(true)
-{
-  DS_LOG_DEBUG("%p", this);
-}
-
-DeviceStorageRequest::~DeviceStorageRequest()
-{
-  DS_LOG_DEBUG("%p", this);
-  if (mId != DeviceStorageRequestManager::INVALID_ID) {
-    /* Cursors may be freed without completing if the caller does not
-       call continue until there is no data left. */
-    MOZ_ASSERT(mMultipleResolve, "Still has valid ID but request being freed!");
-    Reject(POST_ERROR_EVENT_UNKNOWN);
-  }
-}
-
-void
-DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
-                                 already_AddRefed<DeviceStorageFile>&& aFile,
-                                 uint32_t aId)
-{
-  DS_LOG_DEBUG("%p manages %p", aManager, this);
-  mManager = aManager;
-  mFile = aFile;
-  mId = aId;
-  MOZ_ASSERT(mManager);
-  MOZ_ASSERT(mFile);
-  MOZ_ASSERT(mId != DeviceStorageRequestManager::INVALID_ID);
-}
-
-void
-DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
-                                 already_AddRefed<DeviceStorageFile>&& aFile,
-                                 uint32_t aRequest,
-                                 BlobImpl* aBlob)
-{
-  Initialize(aManager, Move(aFile), aRequest);
-  mBlob = aBlob;
-  mCheckBlob = true;
-  mCheckFile = true;
-  MOZ_ASSERT(mBlob);
-}
-
-void
-DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
-                                 already_AddRefed<DeviceStorageFile>&& aFile,
-                                 uint32_t aRequest,
-                                 DeviceStorageFileDescriptor* aDSFileDescriptor)
-{
-  Initialize(aManager, Move(aFile), aRequest);
-  mDSFileDescriptor = aDSFileDescriptor;
-  MOZ_ASSERT(mDSFileDescriptor);
-}
-
-DeviceStorageAccessType
-DeviceStorageRequest::GetAccess() const
-{
-  return mAccess;
-}
-
-void
-DeviceStorageRequest::GetStorageType(nsAString& aType) const
-{
-  aType = mFile->mStorageType;
-}
-
-nsresult
-DeviceStorageRequest::Cancel()
-{
-  return Reject(POST_ERROR_EVENT_PERMISSION_DENIED);
-}
-
-nsresult
-DeviceStorageRequest::Allow()
-{
-  if (mUseMainThread && !NS_IsMainThread()) {
-    RefPtr<DeviceStorageRequest> self = this;
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
-    {
-      self->Allow();
-    });
-    return NS_DispatchToMainThread(r.forget());
-  }
-
-  nsresult rv = AllowInternal();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    const char *reason;
-    switch (rv) {
-      case NS_ERROR_ILLEGAL_VALUE:
-        reason = POST_ERROR_EVENT_ILLEGAL_TYPE;
-        break;
-      case NS_ERROR_DOM_SECURITY_ERR:
-        reason = POST_ERROR_EVENT_PERMISSION_DENIED;
-        break;
-      default:
-        reason = POST_ERROR_EVENT_UNKNOWN;
-        break;
-    }
-    return Reject(reason);
-  }
-  return rv;
-}
-
-DeviceStorageFile*
-DeviceStorageRequest::GetFile() const
-{
-  MOZ_ASSERT(mFile);
-  return mFile;
-}
-
-DeviceStorageFileDescriptor*
-DeviceStorageRequest::GetFileDescriptor() const
-{
-  MOZ_ASSERT(mDSFileDescriptor);
-  return mDSFileDescriptor;
-}
-
-DeviceStorageRequestManager*
-DeviceStorageRequest::GetManager() const
-{
-  return mManager;
-}
-
-nsresult
-DeviceStorageRequest::Prepare()
-{
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequest::CreateSendParams(DeviceStorageParams& aParams)
-{
-  MOZ_ASSERT_UNREACHABLE("Cannot send to parent, missing param creator");
-  return NS_ERROR_UNEXPECTED;
-}
-
-nsresult
-DeviceStorageRequest::AllowInternal()
-{
-  MOZ_ASSERT(mManager->IsOwningThread() || NS_IsMainThread());
-
-  nsresult rv = Prepare();
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  if (mCheckBlob && (!mBlob ||
-      !typeChecker->Check(mFile->mStorageType, mBlob))) {
-    return NS_ERROR_ILLEGAL_VALUE;
-  }
-  if (mCheckFile && (!mFile->mFile ||
-      !typeChecker->Check(mFile->mStorageType, mFile->mFile))) {
-    return NS_ERROR_ILLEGAL_VALUE;
-  }
-
-  mSendToParent = mSendToParent && !XRE_IsParentProcess();
-  if (mSendToParent) {
-    return SendToParentProcess();
-  }
-
-  if (mUseStreamTransport) {
-    DS_LOG_INFO("run stream transport %u", mId);
-    nsCOMPtr<nsIEventTarget> target
-      = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
-    MOZ_ASSERT(target);
-    nsCOMPtr<nsIRunnable> self = this;
-    return target->Dispatch(self.forget(), NS_DISPATCH_NORMAL);
-  }
-
-  DS_LOG_INFO("run %u", mId);
-  return Run();
-}
-
-nsresult
-DeviceStorageRequest::SendToParentProcess()
-{
-  // PContent can only be used on the main thread
-  if (!NS_IsMainThread()) {
-    RefPtr<DeviceStorageRequest> self = this;
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
-    {
-      nsresult rv = self->SendToParentProcess();
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        self->Reject(POST_ERROR_EVENT_UNKNOWN);
-      }
-    });
-    return NS_DispatchToMainThread(r.forget());
-  }
-
-  MOZ_ASSERT(NS_IsMainThread());
-  DS_LOG_INFO("request parent %u", mId);
-
-  DeviceStorageParams params;
-  nsresult rv = CreateSendParams(params);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(this);
-  ContentChild::GetSingleton()
-    ->SendPDeviceStorageRequestConstructor(child, params);
-  return NS_OK;
-}
-
-DeviceStorageCursorRequest::DeviceStorageCursorRequest()
-  : mIndex(0)
-  , mSince(0)
-{
-  mAccess = DEVICE_STORAGE_ACCESS_READ;
-  mUseStreamTransport = true;
-  mMultipleResolve = true;
-  DS_LOG_INFO("");
-}
-
-void
-DeviceStorageCursorRequest::Initialize(DeviceStorageRequestManager* aManager,
-                                       already_AddRefed<DeviceStorageFile>&& aFile,
-                                       uint32_t aRequest,
-                                       PRTime aSince)
-{
-  Initialize(aManager, Move(aFile), aRequest);
-  mStorageType = mFile->mStorageType;
-  mSince = aSince;
-}
-
-void
-DeviceStorageCursorRequest::AddFiles(size_t aSize)
-{
-  mFiles.SetCapacity(mFiles.Length() + aSize);
-}
-
-void
-DeviceStorageCursorRequest::AddFile(already_AddRefed<DeviceStorageFile> aFile)
-{
-  mFiles.AppendElement(aFile);
-}
-
-nsresult
-DeviceStorageCursorRequest::SendContinueToParentProcess()
-{
-  if (!NS_IsMainThread()) {
-    RefPtr<DeviceStorageCursorRequest> self = this;
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
-    {
-      self->SendContinueToParentProcess();
-    });
-    return NS_DispatchToMainThread(r.forget());
-  }
-
-  MOZ_ASSERT(NS_IsMainThread());
-  DS_LOG_INFO("request parent %u", mId);
-
-  DeviceStorageRequestChild* child
-    = new DeviceStorageRequestChild(this);
-  DeviceStorageGetParams params(mStorageType,
-                                mFile->mStorageName,
-                                mFile->mRootDir,
-                                mFile->mPath);
-  ContentChild::GetSingleton()
-    ->SendPDeviceStorageRequestConstructor(child, params);
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageCursorRequest::Continue()
-{
-  if (!NS_IsMainThread()) {
-    /* The MIME service can only be accessed from the main thread */
-    RefPtr<DeviceStorageCursorRequest> self = this;
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
-    {
-      self->Continue();
-    });
-    nsresult rv = NS_DispatchToMainThread(r.forget());
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-    return rv;
-  }
-
-  DS_LOG_INFO("%u", mId);
-
-  RefPtr<DeviceStorageFile> file;
-  while (!file && mIndex < mFiles.Length()) {
-    file = mFiles[mIndex].forget();
-    ++mIndex;
-  }
-
-  if (!file) {
-    // No more files remaining, complete cursor
-    return Resolve();
-  }
-
-  file->CalculateMimeType();
-  if (XRE_IsParentProcess()) {
-    return Resolve(file);
-  }
-
-  mFile = file;
-
-  nsresult rv = SendContinueToParentProcess();
-  if (NS_FAILED(rv)) {
-    return Reject(POST_ERROR_EVENT_UNKNOWN);
-  }
-  return rv;
-}
-
-NS_IMETHODIMP
-DeviceStorageCursorRequest::Run()
-{
-  if (mFile->mFile) {
-    bool check;
-    mFile->mFile->IsDirectory(&check);
-    if (!check) {
-      return Reject(POST_ERROR_EVENT_FILE_NOT_ENUMERABLE);
-    }
-  }
-
-  mFile->CollectFiles(mFiles, mSince);
-  return Continue();
-}
-
-nsresult
-DeviceStorageCursorRequest::CreateSendParams(DeviceStorageParams& aParams)
-{
-  DeviceStorageEnumerationParams params(mFile->mStorageType,
-                                        mFile->mStorageName,
-                                        mFile->mRootDir,
-                                        mSince);
-  aParams = params;
-  return NS_OK;
-}
-
-class DeviceStorageCreateFdRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageCreateFdRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_CREATE;
-    mUseStreamTransport = true;
-    mCheckFile = true;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsString fullPath;
-    mFile->GetFullPath(fullPath);
-    MOZ_ASSERT(!fullPath.IsEmpty());
-
-    bool check = false;
-    mFile->mFile->Exists(&check);
-    if (check) {
-      return Reject(POST_ERROR_EVENT_FILE_EXISTS);
-    }
-
-    nsresult rv = mFile->CreateFileDescriptor(
-                  mDSFileDescriptor->mFileDescriptor);
-
-    if (NS_FAILED(rv)) {
-      mFile->mFile->Remove(false);
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-
-    return Resolve(fullPath);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageCreateFdParams params;
-    params.type() = mFile->mStorageType;
-    params.storageName() = mFile->mStorageName;
-    params.relpath() = mFile->mPath;
-    aParams = params;
-
-    mFile->Dump("DeviceStorageCreateFdParams");
-    return NS_OK;
-  }
-};
-
-class DeviceStorageCreateRequest final
-  : public DeviceStorageRequest
-{
-public:
-  using DeviceStorageRequest::Initialize;
-
-  DeviceStorageCreateRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_CREATE;
-    mUseStreamTransport = true;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    ErrorResult rv;
-    nsCOMPtr<nsIInputStream> stream;
-    mBlob->GetInternalStream(getter_AddRefs(stream), rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-
-    bool check = false;
-    mFile->mFile->Exists(&check);
-    if (check) {
-      return Reject(POST_ERROR_EVENT_FILE_EXISTS);
-    }
-
-    rv = mFile->Write(stream);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      mFile->mFile->Remove(false);
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-
-    nsString fullPath;
-    mFile->GetFullPath(fullPath);
-    return Resolve(fullPath);
-  }
-
-  void Initialize(DeviceStorageRequestManager* aManager,
-                  already_AddRefed<DeviceStorageFile>&& aFile,
-                  uint32_t aRequest) override
-  {
-    DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
-    mUseMainThread = mFile->mPath.IsEmpty();
-  }
-
-protected:
-  nsresult Prepare() override
-  {
-    if (!mFile->mPath.IsEmpty()) {
-      // Checks have already been performed when request was created
-      return NS_OK;
-    }
-
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
-    if (!mimeSvc) {
-      return NS_ERROR_FAILURE;
-    }
-
-    // if mimeType or extension are null, the request will be rejected
-    // in DeviceStorageRequest::AllowInternal when the type checker
-    // verifies the file path
-    nsString mimeType;
-    mBlob->GetType(mimeType);
-
-    nsCString extension;
-    mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
-                                 EmptyCString(), extension);
-
-    char buffer[32];
-    NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
-
-    nsAutoString path;
-    path.AssignLiteral(buffer);
-    path.Append('.');
-    path.AppendASCII(extension.get());
-
-    RefPtr<DeviceStorageFile> file
-      = DeviceStorageFile::CreateUnique(mFile->mStorageType,
-                                        mFile->mStorageName, path,
-                                        nsIFile::NORMAL_FILE_TYPE, 00600);
-    if (!file) {
-      return NS_ERROR_FAILURE;
-    }
-    if (!file->IsSafePath()) {
-      return NS_ERROR_DOM_SECURITY_ERR;
-    }
-
-    mFile = file.forget();
-    return NS_OK;
-  }
-
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    BlobChild* actor
-      = ContentChild::GetSingleton()->GetOrCreateActorForBlobImpl(mBlob);
-    if (!actor) {
-      return NS_ERROR_FAILURE;
-    }
-
-    DeviceStorageAddParams params;
-    params.blobChild() = actor;
-    params.type() = mFile->mStorageType;
-    params.storageName() = mFile->mStorageName;
-    params.relpath() = mFile->mPath;
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageAppendRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageAppendRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_WRITE;
-    mUseStreamTransport = true;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    ErrorResult rv;
-    nsCOMPtr<nsIInputStream> stream;
-    mBlob->GetInternalStream(getter_AddRefs(stream), rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-
-    bool check = false;
-    mFile->mFile->Exists(&check);
-    if (!check) {
-      return Reject(POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
-    }
-
-    rv = mFile->Append(stream);
-    if (NS_WARN_IF(rv.Failed())) {
-      rv.SuppressException();
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-
-    nsString fullPath;
-    mFile->GetFullPath(fullPath);
-    return Resolve(fullPath);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    BlobChild* actor
-      = ContentChild::GetSingleton()->GetOrCreateActorForBlobImpl(mBlob);
-    if (!actor) {
-      return NS_ERROR_FAILURE;
-    }
-
-    DeviceStorageAppendParams params;
-    params.blobChild() = actor;
-    params.type() = mFile->mStorageType;
-    params.storageName() = mFile->mStorageName;
-    params.relpath() = mFile->mPath;
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageOpenRequest final
-  : public DeviceStorageRequest
-{
-public:
-  using DeviceStorageRequest::Initialize;
-
-  DeviceStorageOpenRequest()
-  {
-    mUseMainThread = true;
-    mUseStreamTransport = true;
-    mCheckFile = true;
-    DS_LOG_INFO("");
-  }
-
-  void Initialize(DeviceStorageRequestManager* aManager,
-                  already_AddRefed<DeviceStorageFile>&& aFile,
-                  uint32_t aRequest) override
-  {
-    DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
-    mAccess = mFile->mEditable ? DEVICE_STORAGE_ACCESS_WRITE
-                               : DEVICE_STORAGE_ACCESS_READ;
-  }
-
-  NS_IMETHOD Run() override
-  {
-    if (!mFile->mEditable) {
-      bool check = false;
-      mFile->mFile->Exists(&check);
-      if (!check) {
-        return Reject(POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
-      }
-    }
-
-    nsresult rv = mFile->CalculateSizeAndModifiedDate();
-    if (NS_FAILED(rv)) {
-      return Reject(POST_ERROR_EVENT_UNKNOWN);
-    }
-
-    return Resolve(mFile);
-  }
-
-protected:
-  nsresult Prepare() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mFile->CalculateMimeType();
-    return NS_OK;
-  }
-
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageGetParams params(mFile->mStorageType,
-                                  mFile->mStorageName,
-                                  mFile->mRootDir,
-                                  mFile->mPath);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageDeleteRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageDeleteRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_WRITE;
-    mUseStreamTransport = true;
-    mCheckFile = true;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    mFile->Remove();
-    bool check = false;
-    mFile->mFile->Exists(&check);
-    if (check) {
-      return Reject(POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
-    }
-
-    nsString fullPath;
-    mFile->GetFullPath(fullPath);
-    return Resolve(fullPath);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageDeleteParams params(mFile->mStorageType,
-                                     mFile->mStorageName,
-                                     mFile->mPath);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageFreeSpaceRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageFreeSpaceRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_READ;
-    mUseStreamTransport = true;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    int64_t freeSpace = 0;
-    if (mFile) {
-      mFile->GetStorageFreeSpace(&freeSpace);
-    }
-    return Resolve(static_cast<uint64_t>(freeSpace));
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageFreeSpaceParams params(mFile->mStorageType,
-                                        mFile->mStorageName);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageUsedSpaceRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageUsedSpaceRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_READ;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    if (mManager->IsOwningThread()) {
-      // this needs to be dispatched to only one (1)
-      // thread or we will do more work than required.
-      DeviceStorageUsedSpaceCache* usedSpaceCache
-        = DeviceStorageUsedSpaceCache::CreateOrGet();
-      MOZ_ASSERT(usedSpaceCache);
-      nsCOMPtr<nsIRunnable> self = this;
-      usedSpaceCache->Dispatch(self.forget());
-      return NS_OK;
-    }
-
-    uint64_t picturesUsage = 0, videosUsage = 0,
-             musicUsage = 0, totalUsage = 0;
-    mFile->AccumDiskUsage(&picturesUsage, &videosUsage,
-                          &musicUsage, &totalUsage);
-
-    const nsString& type = mFile->mStorageType;
-    if (type.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
-      totalUsage = picturesUsage;
-    } else if (type.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
-      totalUsage = videosUsage;
-    } else if (type.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
-      totalUsage = musicUsage;
-    }
-    return Resolve(totalUsage);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageUsedSpaceParams params(mFile->mStorageType,
-                                        mFile->mStorageName);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageAvailableRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageAvailableRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_READ;
-    mSendToParent = false;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsString state = NS_LITERAL_STRING("unavailable");
-    if (mFile) {
-      mFile->GetStatus(state);
-    }
-    return Resolve(state);
-  }
-};
-
-class DeviceStorageStatusRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageStatusRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_READ;
-    mSendToParent = false;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsString state = NS_LITERAL_STRING("undefined");
-    if (mFile) {
-      mFile->GetStorageStatus(state);
-    }
-    return Resolve(state);
-  }
-};
-
-class DeviceStorageWatchRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageWatchRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_READ;
-    mSendToParent = false;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    return Resolve();
-  }
-};
-
-class DeviceStorageFormatRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageFormatRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_WRITE;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsString state = NS_LITERAL_STRING("unavailable");
-    if (mFile) {
-      mFile->DoFormat(state);
-    }
-    return Resolve(state);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageFormatParams params(mFile->mStorageType,
-                                     mFile->mStorageName);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageMountRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageMountRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_WRITE;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsString state = NS_LITERAL_STRING("unavailable");
-    if (mFile) {
-      mFile->DoMount(state);
-    }
-    return Resolve(state);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageMountParams params(mFile->mStorageType,
-                                    mFile->mStorageName);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStorageUnmountRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageUnmountRequest()
-  {
-    mAccess = DEVICE_STORAGE_ACCESS_WRITE;
-    DS_LOG_INFO("");
-  }
-
-  NS_IMETHOD Run() override
-  {
-    nsString state = NS_LITERAL_STRING("unavailable");
-    if (mFile) {
-      mFile->DoUnmount(state);
-    }
-    return Resolve(state);
-  }
-
-protected:
-  nsresult CreateSendParams(DeviceStorageParams& aParams) override
-  {
-    DeviceStorageUnmountParams params(mFile->mStorageType,
-                                      mFile->mStorageName);
-    aParams = params;
-    return NS_OK;
-  }
-};
-
-class DeviceStoragePermissionCheck final
-  : public nsIContentPermissionRequest
-  , public nsIRunnable
-{
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStoragePermissionCheck,
-                                           nsIContentPermissionRequest)
-
-  DeviceStoragePermissionCheck(
-    already_AddRefed<DeviceStorageRequest>&& aRequest,
-    uint64_t aWindowID, const PrincipalInfo &aPrincipalInfo)
-    : mRequest(Move(aRequest))
-    , mWindowID(aWindowID)
-    , mPrincipalInfo(aPrincipalInfo)
-  {
-    MOZ_ASSERT(mRequest);
-  }
-
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    if (DeviceStorageStatics::IsPromptTesting()) {
-      return Allow(JS::UndefinedHandleValue);
-    }
-
-    mWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID)->AsInner();
-    if (NS_WARN_IF(!mWindow)) {
-      return Cancel();
-    }
-
-    nsresult rv;
-    mPrincipal = PrincipalInfoToPrincipal(mPrincipalInfo, &rv);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return Cancel();
-    }
-
-    mRequester = new nsContentPermissionRequester(mWindow);
-    return nsContentPermissionUtils::AskPermission(this, mWindow);
-  }
-
-  NS_IMETHOD Cancel() override
-  {
-    return Resolve(false);
-  }
-
-  NS_IMETHOD Allow(JS::HandleValue aChoices) override
-  {
-    MOZ_ASSERT(aChoices.isUndefined());
-    return Resolve(true);
-  }
-
-  NS_IMETHOD GetTypes(nsIArray** aTypes) override
-  {
-    nsString storageType;
-    mRequest->GetStorageType(storageType);
-    nsCString type;
-    nsresult rv =
-      DeviceStorageTypeChecker::GetPermissionForType(storageType, type);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    nsCString access;
-    rv = DeviceStorageTypeChecker::GetAccessForIndex(mRequest->GetAccess(),
-                                                     access);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    nsTArray<nsString> emptyOptions;
-    return nsContentPermissionUtils::CreatePermissionArray(type, access, emptyOptions, aTypes);
-  }
-
-  NS_IMETHOD GetRequester(nsIContentPermissionRequester** aRequester) override
-  {
-    NS_ENSURE_ARG_POINTER(aRequester);
-
-    nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
-    requester.forget(aRequester);
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal) override
-  {
-    NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetWindow(mozIDOMWindow * *aRequestingWindow) override
-  {
-    NS_IF_ADDREF(*aRequestingWindow = mWindow);
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetElement(nsIDOMElement * *aRequestingElement) override
-  {
-    *aRequestingElement = nullptr;
-    return NS_OK;
-  }
-
-private:
-  nsresult Resolve(bool aResolve)
-  {
-    mRequest->GetManager()->StorePermission(mRequest->GetAccess(), aResolve);
-    mRequest->PermissionCacheMissed();
-    if (aResolve) {
-      return mRequest->Allow();
-    }
-    return mRequest->Cancel();
-  }
-
-  virtual ~DeviceStoragePermissionCheck()
-  { }
-
-  RefPtr<DeviceStorageRequest> mRequest;
-  uint64_t mWindowID;
-  PrincipalInfo mPrincipalInfo;
-  nsCOMPtr<nsPIDOMWindowInner> mWindow;
-  nsCOMPtr<nsIPrincipal> mPrincipal;
-  nsCOMPtr<nsIContentPermissionRequester> mRequester;
-};
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeviceStoragePermissionCheck)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentPermissionRequest)
-  NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
-  NS_INTERFACE_MAP_ENTRY(nsIRunnable)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DeviceStoragePermissionCheck)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DeviceStoragePermissionCheck)
-
-NS_IMPL_CYCLE_COLLECTION(DeviceStoragePermissionCheck,
-                         mWindow)
-
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDeviceStorage)
-  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
-  /* nsISupports is an ambiguous base of nsDOMDeviceStorage
-     so we have to work around that. */
-  if ( aIID.Equals(NS_GET_IID(nsDOMDeviceStorage)) )
-    foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
-  else
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-NS_IMPL_ADDREF_INHERITED(nsDOMDeviceStorage, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorage, DOMEventTargetHelper)
-
-int nsDOMDeviceStorage::sInstanceCount = 0;
-
-nsDOMDeviceStorage::nsDOMDeviceStorage(nsPIDOMWindowInner* aWindow)
-  : DOMEventTargetHelper(aWindow)
-  , mIsShareable(false)
-  , mIsRemovable(false)
-  , mInnerWindowID(0)
-  , mOwningThread(NS_GetCurrentThread())
-{
-  MOZ_ASSERT(NS_IsMainThread()); // worker support incomplete
-  sInstanceCount++;
-  DS_LOG_DEBUG("%p (%d)", this, sInstanceCount);
-}
-
-nsresult
-nsDOMDeviceStorage::CheckPermission(
-  already_AddRefed<DeviceStorageRequest>&& aRequest)
-{
-  MOZ_ASSERT(mManager);
-  RefPtr<DeviceStorageRequest> request(aRequest);
-  uint32_t cache = mManager->CheckPermission(request->GetAccess());
-  switch (cache) {
-    case nsIPermissionManager::ALLOW_ACTION:
-      return request->Allow();
-    case nsIPermissionManager::DENY_ACTION:
-      return request->Cancel();
-    case nsIPermissionManager::PROMPT_ACTION:
-    default:
-    {
-      nsCOMPtr<nsIThread> mainThread;
-      nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return request->Reject(POST_ERROR_EVENT_UNKNOWN);
-      }
-
-      return mainThread->Dispatch(
-        MakeAndAddRef<DeviceStoragePermissionCheck>(request.forget(),
-                                                    mInnerWindowID,
-                                                    *mPrincipalInfo),
-        NS_DISPATCH_NORMAL);
-    }
-  }
-}
-
-bool
-nsDOMDeviceStorage::IsOwningThread()
-{
-  bool owner = false;
-  mOwningThread->IsOnCurrentThread(&owner);
-  return owner;
-}
-
-nsresult
-nsDOMDeviceStorage::DispatchToOwningThread(
-  already_AddRefed<nsIRunnable>&& aRunnable)
-{
-  return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
-}
-
-/* virtual */ JSObject*
-nsDOMDeviceStorage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return DeviceStorageBinding::Wrap(aCx, this, aGivenProto);
-}
-
-nsresult
-nsDOMDeviceStorage::Init(nsPIDOMWindowInner* aWindow, const nsAString &aType,
-                         const nsAString &aVolName)
-{
-  MOZ_ASSERT(aWindow);
-  mInnerWindowID = aWindow->WindowID();
-
-  SetRootDirectoryForType(aType, aVolName);
-  if (!mRootDirectory) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  nsresult rv;
-  DeviceStorageStatics::AddListener(this);
-  if (!mStorageName.IsEmpty()) {
-    mIsDefaultLocation = Default();
-
-#ifdef MOZ_WIDGET_GONK
-    if (DeviceStorageTypeChecker::IsVolumeBased(mStorageType)) {
-      nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-      if (NS_WARN_IF(!vs)) {
-        return NS_ERROR_FAILURE;
-      }
-      nsCOMPtr<nsIVolume> vol;
-      rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-      bool isFake;
-      rv = vol->GetIsFake(&isFake);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-      mIsShareable = !isFake;
-      bool isRemovable;
-      rv = vol->GetIsHotSwappable(&isRemovable);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-      mIsRemovable = isRemovable;
-    }
-#endif
-  }
-
-  nsCOMPtr<nsIPrincipal> principal;
-  rv = CheckPrincipal(aWindow, aType.EqualsLiteral(DEVICESTORAGE_APPS), getter_AddRefs(principal));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  mPrincipalInfo = new PrincipalInfo();
-  rv = PrincipalToPrincipalInfo(principal, mPrincipalInfo);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  mManager = new DeviceStorageRequestManager();
-  DS_LOG_DEBUG("%p owns %p", this, mManager.get());
-  return NS_OK;
-}
-
-nsDOMDeviceStorage::~nsDOMDeviceStorage()
-{
-  DS_LOG_DEBUG("%p (%d)", this, sInstanceCount);
-  MOZ_ASSERT(IsOwningThread());
-  sInstanceCount--;
-  DeviceStorageStatics::RemoveListener(this);
-}
-
-// static
-nsresult
-nsDOMDeviceStorage::CheckPrincipal(nsPIDOMWindowInner* aWindow,
-                                   bool aIsAppsStorage,
-                                   nsIPrincipal** aPrincipal)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aWindow);
-
-  // Grab the principal of the document
-  nsCOMPtr<nsIDocument> doc = aWindow->GetDoc();
-  if (!doc) {
-    return NS_ERROR_FAILURE;
-  }
-  nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
-
-  // the 'apps' type is special.  We only want this exposed
-  // if the caller has the "webapps-manage" permission.
-  if (aIsAppsStorage) {
-    nsCOMPtr<nsIPermissionManager> permissionManager
-      = services::GetPermissionManager();
-    NS_ENSURE_TRUE(permissionManager, NS_ERROR_FAILURE);
-
-    uint32_t permission;
-    nsresult rv
-      = permissionManager->TestPermissionFromPrincipal(principal,
-                                                       "webapps-manage",
-                                                       &permission);
-
-    if (NS_FAILED(rv) || permission != nsIPermissionManager::ALLOW_ACTION) {
-      return NS_ERROR_NOT_AVAILABLE;
-    }
-  }
-
-  principal.forget(aPrincipal);
-  return NS_OK;
-}
-
-void
-nsDOMDeviceStorage::Shutdown()
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  if (mManager) {
-    mManager->Shutdown();
-    mManager = nullptr;
-  }
-
-  if (mFileSystem) {
-    mFileSystem->Shutdown();
-    mFileSystem = nullptr;
-  }
-
-  DeviceStorageStatics::RemoveListener(this);
-}
-
-StaticAutoPtr<nsTArray<nsString>> nsDOMDeviceStorage::sVolumeNameCache;
-
-// static
-void nsDOMDeviceStorage::InvalidateVolumeCaches()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  sVolumeNameCache = nullptr;
-}
-
-// static
-void
-nsDOMDeviceStorage::GetOrderedVolumeNames(
-  const nsAString& aType,
-  nsDOMDeviceStorage::VolumeNameArray& aVolumeNames)
-{
-  if (!DeviceStorageTypeChecker::IsVolumeBased(aType)) {
-    aVolumeNames.Clear();
-    return;
-  }
-  GetOrderedVolumeNames(aVolumeNames);
-}
-
-// static
-void
-nsDOMDeviceStorage::GetOrderedVolumeNames(
-  nsDOMDeviceStorage::VolumeNameArray& aVolumeNames)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (sVolumeNameCache && sVolumeNameCache->Length() > 0) {
-    aVolumeNames.AppendElements(*sVolumeNameCache);
-    return;
-  }
-#ifdef MOZ_WIDGET_GONK
-  nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
-  if (vs) {
-    nsCOMPtr<nsIArray> volNames;
-    vs->GetVolumeNames(getter_AddRefs(volNames));
-    uint32_t length = -1;
-    volNames->GetLength(&length);
-    for (uint32_t i = 0; i < length; i++) {
-      nsCOMPtr<nsISupportsString> str = do_QueryElementAt(volNames, i);
-      if (str) {
-        nsAutoString s;
-        if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) {
-          aVolumeNames.AppendElement(s);
-        }
-      }
-    }
-
-    // If the volume sdcard exists, then we want it to be first.
-
-    VolumeNameArray::index_type sdcardIndex;
-    sdcardIndex = aVolumeNames.IndexOf(NS_LITERAL_STRING("sdcard"));
-    if (sdcardIndex != VolumeNameArray::NoIndex && sdcardIndex > 0) {
-      aVolumeNames.RemoveElementAt(sdcardIndex);
-      aVolumeNames.InsertElementAt(0, NS_LITERAL_STRING("sdcard"));
-    }
-  }
-#endif
-  if (aVolumeNames.IsEmpty()) {
-    aVolumeNames.AppendElement(EmptyString());
-  }
-  sVolumeNameCache = new nsTArray<nsString>;
-  sVolumeNameCache->AppendElements(aVolumeNames);
-}
-
-// static
-void
-nsDOMDeviceStorage::CreateDeviceStorageFor(nsPIDOMWindowInner* aWin,
-                                           const nsAString &aType,
-                                           nsDOMDeviceStorage** aStore)
-{
-  nsString storageName;
-  GetDefaultStorageName(aType, storageName);
-
-  RefPtr<nsDOMDeviceStorage> ds = new nsDOMDeviceStorage(aWin);
-  if (NS_FAILED(ds->Init(aWin, aType, storageName))) {
-    *aStore = nullptr;
-    return;
-  }
-  ds.forget(aStore);
-}
-
-// static
-void
-nsDOMDeviceStorage::CreateDeviceStorageByNameAndType(
-  nsPIDOMWindowInner* aWin,
-  const nsAString& aName,
-  const nsAString& aType,
-  nsDOMDeviceStorage** aStore)
-{
-  if (!DeviceStorageTypeChecker::IsVolumeBased(aType)) {
-    RefPtr<nsDOMDeviceStorage> storage = new nsDOMDeviceStorage(aWin);
-    if (NS_FAILED(storage->Init(aWin, aType, EmptyString()))) {
-      *aStore = nullptr;
-      return;
-    }
-    NS_ADDREF(*aStore = storage.get());
-    return;
-  }
-
-  RefPtr<nsDOMDeviceStorage> storage = GetStorageByNameAndType(aWin,
-                                                                 aName,
-                                                                 aType);
-  if (!storage) {
-    *aStore = nullptr;
-    return;
-  }
-  NS_ADDREF(*aStore = storage.get());
-}
-
-bool
-nsDOMDeviceStorage::Equals(nsPIDOMWindowInner* aWin,
-                           const nsAString& aName,
-                           const nsAString& aType)
-{
-  MOZ_ASSERT(aWin);
-
-  return aWin && aWin->WindowID() == mInnerWindowID &&
-         mStorageName.Equals(aName) &&
-         mStorageType.Equals(aType);
-}
-
-// static
-bool
-nsDOMDeviceStorage::ParseFullPath(const nsAString& aFullPath,
-                                  nsAString& aOutStorageName,
-                                  nsAString& aOutStoragePath)
-{
-  aOutStorageName.Truncate();
-  aOutStoragePath.Truncate();
-
-  NS_NAMED_LITERAL_STRING(slash, "/");
-
-  nsDependentSubstring storageName;
-
-  if (StringBeginsWith(aFullPath, slash)) {
-    int32_t slashIndex = aFullPath.FindChar('/', 1);
-    if (slashIndex == kNotFound) {
-      // names of the form /filename are illegal
-      return false;
-    }
-    storageName.Rebind(aFullPath, 1, slashIndex - 1);
-    aOutStoragePath = Substring(aFullPath, slashIndex + 1);
-  } else {
-    aOutStoragePath = aFullPath;
-  }
-  // If no volume name was specified in aFullPath, then aOutStorageName
-  // will wind up being the empty string. It's up to the caller to figure
-  // out which storage name to actually use.
-  aOutStorageName = storageName;
-  return true;
-}
-
-already_AddRefed<nsDOMDeviceStorage>
-nsDOMDeviceStorage::GetStorage(const nsAString& aFullPath,
-                               nsAString& aOutStoragePath)
-{
-  nsString storageName;
-  if (!ParseFullPath(aFullPath, storageName, aOutStoragePath)) {
-    return nullptr;
-  }
-  RefPtr<nsDOMDeviceStorage> ds;
-  if (storageName.IsEmpty()) {
-    ds = this;
-  } else {
-    ds = GetStorageByName(storageName);
-  }
-  return ds.forget();
-}
-
-already_AddRefed<nsDOMDeviceStorage>
-nsDOMDeviceStorage::GetStorageByName(const nsAString& aStorageName)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<nsDOMDeviceStorage> ds;
-
-  if (mStorageName.Equals(aStorageName)) {
-    ds = this;
-    return ds.forget();
-  }
-
-  return GetStorageByNameAndType(GetOwner(), aStorageName, mStorageType);
-}
-
-// static
-already_AddRefed<nsDOMDeviceStorage>
-nsDOMDeviceStorage::GetStorageByNameAndType(nsPIDOMWindowInner* aWin,
-                                            const nsAString& aStorageName,
-                                            const nsAString& aType)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RefPtr<nsDOMDeviceStorage> ds;
-
-  VolumeNameArray volNames;
-  GetOrderedVolumeNames(volNames);
-  VolumeNameArray::size_type numVolumes = volNames.Length();
-  VolumeNameArray::index_type i;
-  for (i = 0; i < numVolumes; i++) {
-    if (volNames[i].Equals(aStorageName)) {
-      ds = new nsDOMDeviceStorage(aWin);
-      nsresult rv = ds->Init(aWin, aType, aStorageName);
-      if (NS_FAILED(rv)) {
-        return nullptr;
-      }
-      return ds.forget();
-    }
-  }
-  return nullptr;
-}
-
-// static
-void
-nsDOMDeviceStorage::GetDefaultStorageName(const nsAString& aStorageType,
-                                          nsAString& aStorageName)
-{
-  if (!DeviceStorageTypeChecker::IsVolumeBased(aStorageType)) {
-    // The storage name will be the empty string
-    aStorageName.Truncate();
-    return;
-  }
-
-  // See if the preferred volume is available.
-  nsString prefStorageName;
-  DeviceStorageStatics::GetWritableName(prefStorageName);
-
-  if (!prefStorageName.IsEmpty()) {
-    nsString status;
-    RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(aStorageType,
-                                                            prefStorageName);
-    dsf->GetStorageStatus(status);
-
-    if (!status.EqualsLiteral("NoMedia")) {
-      aStorageName = prefStorageName;
-      return;
-    }
-  }
-
-  // If there is no preferred storage or preferred storage is not presented,
-  // we'll use the first one (which should be sdcard).
-  VolumeNameArray volNames;
-  GetOrderedVolumeNames(volNames);
-  if (volNames.Length() > 0) {
-    aStorageName = volNames[0];
-    // overwrite the value of "device.storage.writable.name"
-    DeviceStorageStatics::SetWritableName(aStorageName);
-    return;
-  }
-
-  // No volumes available, return the empty string. This is normal for
-  // b2g-desktop.
-  aStorageName.Truncate();
-}
-
-bool
-nsDOMDeviceStorage::IsAvailable()
-{
-  RefPtr<DeviceStorageFile> dsf(new DeviceStorageFile(mStorageType, mStorageName));
-  return dsf->IsAvailable();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::Add(Blob* aBlob, ErrorResult& aRv)
-{
-  nsString path;
-  return AddOrAppendNamed(aBlob, path, true, aRv);
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::AddNamed(Blob* aBlob, const nsAString& aPath,
-                             ErrorResult& aRv)
-{
-  if (aPath.IsEmpty()) {
-    aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
-    return nullptr;
-  }
-  return AddOrAppendNamed(aBlob, aPath, true, aRv);
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::AppendNamed(Blob* aBlob, const nsAString& aPath,
-                                ErrorResult& aRv)
-{
-  if (aPath.IsEmpty()) {
-    aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
-    return nullptr;
-  }
-  return AddOrAppendNamed(aBlob, aPath, false, aRv);
-}
-
-uint32_t
-nsDOMDeviceStorage::CreateDOMRequest(DOMRequest** aRequest, ErrorResult& aRv)
-{
-  if (!mManager) {
-    DS_LOG_WARN("shutdown");
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return DeviceStorageRequestManager::INVALID_ID;
-  }
-
-  return mManager->Create(this, aRequest);
-}
-
-uint32_t
-nsDOMDeviceStorage::CreateDOMCursor(DeviceStorageCursorRequest* aRequest, nsDOMDeviceStorageCursor** aCursor, ErrorResult& aRv)
-{
-  if (!mManager) {
-    DS_LOG_WARN("shutdown");
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return DeviceStorageRequestManager::INVALID_ID;
-  }
-
-  return mManager->Create(this, aRequest, aCursor);
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::CreateAndRejectDOMRequest(const char *aReason, ErrorResult& aRv)
-{
-  RefPtr<DOMRequest> request;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(request), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  aRv = mManager->Reject(id, aReason);
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
-                                     bool aCreate, ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-  MOZ_ASSERT(aCreate || !aPath.IsEmpty());
-
-  // if the blob is null here, bail
-  if (!aBlob) {
-    return nullptr;
-  }
-
-  if (IsFullPath(aPath)) {
-    nsString storagePath;
-    RefPtr<nsDOMDeviceStorage> ds = GetStorage(aPath, storagePath);
-    if (!ds) {
-      return CreateAndRejectDOMRequest(POST_ERROR_EVENT_UNKNOWN, aRv);
-    }
-
-    return ds->AddOrAppendNamed(aBlob, storagePath, aCreate, aRv);
-  }
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageFile> dsf;
-  if (aPath.IsEmpty()) {
-    dsf = new DeviceStorageFile(mStorageType, mStorageName);
-  } else {
-    dsf = new DeviceStorageFile(mStorageType, mStorageName, aPath);
-    if (!dsf->IsSafePath()) {
-      aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
-      return domRequest.forget();
-    }
-  }
-
-  RefPtr<DeviceStorageRequest> request;
-  if (aCreate) {
-    request = new DeviceStorageCreateRequest();
-  } else {
-    request = new DeviceStorageAppendRequest();
-  }
-  request->Initialize(mManager, dsf.forget(), id, aBlob->Impl());
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable,
-                                ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  if (IsFullPath(aPath)) {
-    nsString storagePath;
-    RefPtr<nsDOMDeviceStorage> ds = GetStorage(aPath, storagePath);
-    if (!ds) {
-      return CreateAndRejectDOMRequest(POST_ERROR_EVENT_UNKNOWN, aRv);
-    }
-    return ds->GetInternal(storagePath, aEditable, aRv);
-  }
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName,
-                                                          aPath);
-  dsf->SetEditable(aEditable);
-  if (!dsf->IsSafePath()) {
-    return CreateAndRejectDOMRequest(POST_ERROR_EVENT_PERMISSION_DENIED, aRv);
-  }
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageOpenRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  if (IsFullPath(aPath)) {
-    nsString storagePath;
-    RefPtr<nsDOMDeviceStorage> ds = GetStorage(aPath, storagePath);
-    if (!ds) {
-      return CreateAndRejectDOMRequest(POST_ERROR_EVENT_UNKNOWN, aRv);
-    }
-    return ds->Delete(storagePath, aRv);
-  }
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName,
-                                                          aPath);
-  if (!dsf->IsSafePath()) {
-    return CreateAndRejectDOMRequest(POST_ERROR_EVENT_PERMISSION_DENIED, aRv);
-  }
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageDeleteRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageFreeSpaceRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  DebugOnly<DeviceStorageUsedSpaceCache*> usedSpaceCache
-    = DeviceStorageUsedSpaceCache::CreateOrGet();
-  MOZ_ASSERT(usedSpaceCache);
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageUsedSpaceRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::Available(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageAvailableRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::StorageStatus(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageStatusRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::Format(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageFormatRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::Mount(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageMountRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::Unmount(ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageUnmountRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-already_AddRefed<DOMRequest>
-nsDOMDeviceStorage::CreateFileDescriptor(const nsAString& aPath,
-                                         DeviceStorageFileDescriptor* aDSFileDescriptor,
-                                         ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-  MOZ_ASSERT(aDSFileDescriptor);
-
-  DeviceStorageTypeChecker* typeChecker
-    = DeviceStorageTypeChecker::CreateOrGet();
-  if (!typeChecker) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  if (IsFullPath(aPath)) {
-    nsString storagePath;
-    RefPtr<nsDOMDeviceStorage> ds = GetStorage(aPath, storagePath);
-    if (!ds) {
-      return CreateAndRejectDOMRequest(POST_ERROR_EVENT_UNKNOWN, aRv);
-    }
-    return ds->CreateFileDescriptor(storagePath, aDSFileDescriptor, aRv);
-  }
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName,
-                                                          aPath);
-  if (!dsf->IsSafePath()) {
-    return CreateAndRejectDOMRequest(POST_ERROR_EVENT_PERMISSION_DENIED, aRv);
-  }
-
-  if (!typeChecker->Check(mStorageType, dsf->mFile)) {
-    return CreateAndRejectDOMRequest(POST_ERROR_EVENT_ILLEGAL_TYPE, aRv);
-  }
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageCreateFdRequest();
-  request->Initialize(mManager, dsf.forget(), id, aDSFileDescriptor);
-
-  aRv = CheckPermission(request.forget());
-  return domRequest.forget();
-}
-
-bool
-nsDOMDeviceStorage::Default()
-{
-  nsString defaultStorageName;
-  GetDefaultStorageName(mStorageType, defaultStorageName);
-  return mStorageName.Equals(defaultStorageName);
-}
-
-bool
-nsDOMDeviceStorage::CanBeFormatted()
-{
-  // Currently, any volume which can be shared can also be formatted.
-  return mIsShareable;
-}
-
-bool
-nsDOMDeviceStorage::CanBeMounted()
-{
-  // Currently, any volume which can be shared can also be mounted/unmounted.
-  return mIsShareable;
-}
-
-bool
-nsDOMDeviceStorage::CanBeShared()
-{
-  return mIsShareable;
-}
-
-bool
-nsDOMDeviceStorage::IsRemovable()
-{
-  return mIsRemovable;
-}
-
-bool
-nsDOMDeviceStorage::LowDiskSpace()
-{
-  return DeviceStorageStatics::LowDiskSpace();
-}
-
-already_AddRefed<Promise>
-nsDOMDeviceStorage::GetRoot(ErrorResult& aRv)
-{
-  if (!mFileSystem) {
-    mFileSystem = new DeviceStorageFileSystem(mStorageType, mStorageName);
-    mFileSystem->Init(this);
-  }
-  return nullptr;
-}
-
-void
-nsDOMDeviceStorage::GetStorageName(nsAString& aStorageName)
-{
-  aStorageName = mStorageName;
-}
-
-already_AddRefed<DOMCursor>
-nsDOMDeviceStorage::Enumerate(const nsAString& aPath,
-                              const EnumerationParameters& aOptions,
-                              ErrorResult& aRv)
-{
-  return EnumerateInternal(aPath, aOptions, false, aRv);
-}
-
-already_AddRefed<DOMCursor>
-nsDOMDeviceStorage::EnumerateEditable(const nsAString& aPath,
-                                      const EnumerationParameters& aOptions,
-                                      ErrorResult& aRv)
-{
-  return EnumerateInternal(aPath, aOptions, true, aRv);
-}
-
-
-already_AddRefed<DOMCursor>
-nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
-                                      const EnumerationParameters& aOptions,
-                                      bool aEditable, ErrorResult& aRv)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  PRTime since = 0;
-  if (aOptions.mSince.WasPassed() && !aOptions.mSince.Value().IsUndefined()) {
-    since = PRTime(aOptions.mSince.Value().TimeStamp().toDouble());
-  }
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName,
-                                                          aPath,
-                                                          EmptyString());
-  dsf->SetEditable(aEditable);
-
-  RefPtr<DeviceStorageCursorRequest> request = new DeviceStorageCursorRequest();
-  RefPtr<nsDOMDeviceStorageCursor> cursor;
-  uint32_t id = CreateDOMCursor(request, getter_AddRefs(cursor), aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  if (!dsf->IsSafePath()) {
-    aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
-  } else {
-    request->Initialize(mManager, dsf.forget(), id, since);
-    aRv = CheckPermission(request.forget());
-  }
-
-  return cursor.forget();
-}
-
-void
-nsDOMDeviceStorage::OnWritableNameChanged()
-{
-  nsAdoptingString DefaultLocation;
-  GetDefaultStorageName(mStorageType, DefaultLocation);
-
-  mIsDefaultLocation = Default();
-}
-
-#ifdef MOZ_WIDGET_GONK
-void
-nsDOMDeviceStorage::DispatchStatusChangeEvent(nsAString& aStatus)
-{
-  if (aStatus == mLastStatus) {
-    // We've already sent this status, don't bother sending it again.
-    return;
-  }
-  mLastStatus = aStatus;
-}
-
-void
-nsDOMDeviceStorage::DispatchStorageStatusChangeEvent(nsAString& aStorageStatus)
-{
-  if (aStorageStatus == mLastStorageStatus) {
-     // We've already sent this status, don't bother sending it again.
-    return;
-  }
-  mLastStorageStatus = aStorageStatus;
-}
-#endif
-
-void
-nsDOMDeviceStorage::OnFileWatcherUpdate(const nsCString& aData, DeviceStorageFile* aFile)
-{
-  MOZ_ASSERT(IsOwningThread());
-  Notify(aData.get(), aFile);
-}
-
-void
-nsDOMDeviceStorage::OnDiskSpaceWatcher(bool aLowDiskSpace)
-{
-  MOZ_ASSERT(IsOwningThread());
-  RefPtr<DeviceStorageFile> file =
-    new DeviceStorageFile(mStorageType, mStorageName);
-  if (aLowDiskSpace) {
-    Notify("low-disk-space", file);
-  } else {
-    Notify("available-disk-space", file);
-  }
-}
-
-#ifdef MOZ_WIDGET_GONK
-void
-nsDOMDeviceStorage::OnVolumeStateChanged(nsIVolume* aVolume) {
-  MOZ_ASSERT(IsOwningThread());
-
-  // We invalidate the used space cache for the volume that actually changed
-  // state.
-  nsString volName;
-  aVolume->GetName(volName);
-
-  DeviceStorageUsedSpaceCache* usedSpaceCache
-    = DeviceStorageUsedSpaceCache::CreateOrGet();
-  MOZ_ASSERT(usedSpaceCache);
-  usedSpaceCache->Invalidate(volName);
-
-  if (!volName.Equals(mStorageName)) {
-    // Not our volume - we can ignore.
-    return;
-  }
-
-  RefPtr<DeviceStorageFile> dsf(new DeviceStorageFile(mStorageType, mStorageName));
-  nsString status, storageStatus;
-
-  // Get Status (one of "available, unavailable, shared")
-  dsf->GetStatus(status);
-  DispatchStatusChangeEvent(status);
-
-  // Get real volume status (defined in dom/system/gonk/nsIVolume.idl)
-  dsf->GetStorageStatus(storageStatus);
-  DispatchStorageStatusChangeEvent(storageStatus);
-}
-#endif
-
-nsresult
-nsDOMDeviceStorage::Notify(const char* aReason, DeviceStorageFile* aFile)
-{
-  if (!mManager) {
-    return NS_OK;
-  }
-
-  if (mManager->CheckPermission(DEVICE_STORAGE_ACCESS_READ) !=
-      nsIPermissionManager::ALLOW_ACTION) {
-    return NS_OK;
-  }
-
-  if (!mStorageType.Equals(aFile->mStorageType) ||
-      !mStorageName.Equals(aFile->mStorageName)) {
-    // Ignore this
-    return NS_OK;
-  }
-
-  return NS_OK;
-}
-
-void
-nsDOMDeviceStorage::EventListenerWasAdded(const nsAString& aType,
-                                          ErrorResult& aRv,
-                                          JSCompartment* aCompartment)
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  if (!mManager) {
-    return;
-  }
-
-  if (mManager->CheckPermission(DEVICE_STORAGE_ACCESS_READ) !=
-      nsIPermissionManager::PROMPT_ACTION) {
-    return;
-  }
-
-  if (!aType.EqualsLiteral(STORAGE_CHANGE_EVENT)) {
-    return;
-  }
-
-  RefPtr<DOMRequest> domRequest;
-  uint32_t id = CreateDOMRequest(getter_AddRefs(domRequest), aRv);
-  if (aRv.Failed()) {
-    return;
-  }
-
-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
-                                                          mStorageName);
-  RefPtr<DeviceStorageRequest> request = new DeviceStorageWatchRequest();
-  request->Initialize(mManager, dsf.forget(), id);
-  aRv = CheckPermission(request.forget());
-}
-
-Atomic<uint32_t> DeviceStorageRequestManager::sLastRequestId(0);
-
-DeviceStorageRequestManager::DeviceStorageRequestManager()
-  : mOwningThread(NS_GetCurrentThread())
-  , mMutex("DeviceStorageRequestManager::mMutex")
-  , mShutdown(false)
-{
-  DS_LOG_INFO("%p", this);
-  for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mPermissionCache); ++i) {
-    mPermissionCache[i] = nsIPermissionManager::PROMPT_ACTION;
-  }
-}
-
-DeviceStorageRequestManager::~DeviceStorageRequestManager()
-{
-  DS_LOG_INFO("%p pending %zu", this, mPending.Length());
-
-  if (!mPending.IsEmpty()) {
-    MOZ_ASSERT_UNREACHABLE("Should not destroy, still has pending requests");
-    ListIndex i = mPending.Length();
-    while (i > 0) {
-      --i;
-      DS_LOG_ERROR("terminate %u", mPending[i].mId);
-      NS_ProxyRelease(mOwningThread, mPending[i].mRequest.forget());
-    }
-  }
-}
-
-void
-DeviceStorageRequestManager::StorePermission(size_t aAccess, bool aAllow)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aAccess < MOZ_ARRAY_LENGTH(mPermissionCache));
-
-  MutexAutoLock lock(mMutex);
-  mPermissionCache[aAccess] = aAllow ? nsIPermissionManager::ALLOW_ACTION
-                                     : nsIPermissionManager::DENY_ACTION;
-  DS_LOG_INFO("access %zu cache %u", aAccess, mPermissionCache[aAccess]);
-}
-
-uint32_t
-DeviceStorageRequestManager::CheckPermission(size_t aAccess)
-{
-  MOZ_ASSERT(IsOwningThread() || NS_IsMainThread());
-  MOZ_ASSERT(aAccess < MOZ_ARRAY_LENGTH(mPermissionCache));
-
-  MutexAutoLock lock(mMutex);
-  DS_LOG_INFO("access %zu cache %u", aAccess, mPermissionCache[aAccess]);
-  return mPermissionCache[aAccess];
-}
-
-bool
-DeviceStorageRequestManager::IsOwningThread()
-{
-  bool owner = false;
-  mOwningThread->IsOnCurrentThread(&owner);
-  return owner;
-}
-
-nsresult
-DeviceStorageRequestManager::DispatchToOwningThread(
-  already_AddRefed<nsIRunnable>&& aRunnable)
-{
-  return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
-}
-
-nsresult
-DeviceStorageRequestManager::DispatchOrAbandon(
-  uint32_t aId, already_AddRefed<nsIRunnable>&& aRunnable)
-{
-  MutexAutoLock lock(mMutex);
-  if (mShutdown) {
-    /* Dispatching in this situation may result in the runnable being
-       silently discarded but not freed. The runnables themselves are
-       safe to be freed off the owner thread but the dispatch method
-       does not know that. */
-    DS_LOG_DEBUG("shutdown %u", aId);
-    nsCOMPtr<nsIRunnable> runnable(aRunnable);
-    return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
-  }
-
-  nsresult rv = DispatchToOwningThread(Move(aRunnable));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    DS_LOG_ERROR("abandon %u", aId);
-  }
-  return rv;
-}
-
-uint32_t
-DeviceStorageRequestManager::Create(nsDOMDeviceStorage* aDeviceStorage,
-                                    DeviceStorageCursorRequest* aRequest,
-                                    nsDOMDeviceStorageCursor** aCursor)
-{
-  MOZ_ASSERT(aDeviceStorage);
-  MOZ_ASSERT(aRequest);
-  MOZ_ASSERT(aCursor);
-
-  RefPtr<nsDOMDeviceStorageCursor> request
-    = new nsDOMDeviceStorageCursor(aDeviceStorage->GetOwnerGlobal(), aRequest);
-  uint32_t id = CreateInternal(request, true);
-  DS_LOG_INFO("%u", id);
-  request.forget(aCursor);
-  return id;
-}
-
-uint32_t
-DeviceStorageRequestManager::Create(nsDOMDeviceStorage* aDeviceStorage,
-                                    DOMRequest** aRequest)
-{
-  MOZ_ASSERT(aDeviceStorage);
-  MOZ_ASSERT(aRequest);
-
-  RefPtr<DOMRequest> request
-    = new DOMRequest(aDeviceStorage->GetOwnerGlobal());
-  uint32_t id = CreateInternal(request, false);
-  DS_LOG_INFO("%u", id);
-  request.forget(aRequest);
-  return id;
-}
-
-uint32_t
-DeviceStorageRequestManager::CreateInternal(DOMRequest* aRequest, bool aCursor)
-{
-  MOZ_ASSERT(IsOwningThread());
-  MOZ_ASSERT(!mShutdown);
-
-  uint32_t id;
-  do {
-    id = ++sLastRequestId;
-  } while (id == INVALID_ID || Find(id) != mPending.Length());
-
-  ListEntry* entry = mPending.AppendElement();
-  entry->mId = id;
-  entry->mRequest = aRequest;
-  entry->mCursor = aCursor;
-  return entry->mId;
-}
-
-nsresult
-DeviceStorageRequestManager::Resolve(uint32_t aId, bool aForceDispatch)
-{
-  if (aForceDispatch || !IsOwningThread()) {
-    DS_LOG_DEBUG("recv %u", aId);
-    RefPtr<DeviceStorageRequestManager> self = this;
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, aId] () -> void
-    {
-      self->Resolve(aId, false);
-    });
-    return DispatchOrAbandon(aId, r.forget());
-  }
-
-  DS_LOG_INFO("posted %u", aId);
-
-  if (NS_WARN_IF(aId == INVALID_ID)) {
-    DS_LOG_ERROR("invalid");
-    MOZ_ASSERT_UNREACHABLE("resolve invalid request");
-    return NS_OK;
-  }
-
-  ListIndex i = Find(aId);
-  if (NS_WARN_IF(i == mPending.Length())) {
-    return NS_OK;
-  }
-
-  return ResolveInternal(i, JS::UndefinedHandleValue);
-}
-
-nsresult
-DeviceStorageRequestManager::Resolve(uint32_t aId, const nsString& aResult,
-                                     bool aForceDispatch)
-{
-  if (aForceDispatch || !IsOwningThread()) {
-    DS_LOG_DEBUG("recv %u", aId);
-    RefPtr<DeviceStorageRequestManager> self = this;
-    nsString result = aResult;
-    nsCOMPtr<nsIRunnable> r
-      = NS_NewRunnableFunction([self, aId, result] () -> void
-    {
-      self->Resolve(aId, result, false);
-    });
-    return DispatchOrAbandon(aId, r.forget());
-  }
-
-  DS_LOG_INFO("posted %u w/ %s", aId,
-              NS_LossyConvertUTF16toASCII(aResult).get());
-
-  if (NS_WARN_IF(aId == INVALID_ID)) {
-    DS_LOG_WARN("invalid");
-    MOZ_ASSERT_UNREACHABLE("resolve invalid request");
-    return NS_OK;
-  }
-
-  ListIndex i = Find(aId);
-  if (NS_WARN_IF(i == mPending.Length())) {
-    return NS_OK;
-  }
-
-  nsIGlobalObject* global = mPending[i].mRequest->GetOwnerGlobal();
-
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(global))) {
-    return RejectInternal(i, NS_LITERAL_STRING(POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  JS::RootedValue rvalue(jsapi.cx());
-  JS::MutableHandleValue mvalue(&rvalue);
-  if (NS_WARN_IF(!xpc::StringToJsval(jsapi.cx(), aResult, mvalue))) {
-    return RejectInternal(i, NS_LITERAL_STRING(POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  return ResolveInternal(i, rvalue);
-}
-
-nsresult
-DeviceStorageRequestManager::Resolve(uint32_t aId, uint64_t aValue,
-                                     bool aForceDispatch)
-{
-  if (aForceDispatch || !IsOwningThread()) {
-    DS_LOG_DEBUG("recv %u w/ %" PRIu64, aId, aValue);
-    RefPtr<DeviceStorageRequestManager> self = this;
-    nsCOMPtr<nsIRunnable> r
-      = NS_NewRunnableFunction([self, aId, aValue] () -> void
-    {
-      self->Resolve(aId, aValue, false);
-    });
-    return DispatchOrAbandon(aId, r.forget());
-  }
-
-  DS_LOG_INFO("posted %u w/ %" PRIu64, aId, aValue);
-
-  if (NS_WARN_IF(aId == INVALID_ID)) {
-    DS_LOG_ERROR("invalid");
-    MOZ_ASSERT_UNREACHABLE("resolve invalid request");
-    return NS_OK;
-  }
-
-  ListIndex i = Find(aId);
-  if (NS_WARN_IF(i == mPending.Length())) {
-    return NS_OK;
-  }
-
-  JS::RootedValue value(RootingCx(), JS_NumberValue((double)aValue));
-  return ResolveInternal(i, value);
-}
-
-nsresult
-DeviceStorageRequestManager::Resolve(uint32_t aId, DeviceStorageFile* aFile,
-                                     bool aForceDispatch)
-{
-  MOZ_ASSERT(aFile);
-  DS_LOG_DEBUG("recv %u w/ %p", aId, aFile);
-
-  nsString fullPath;
-  aFile->GetFullPath(fullPath);
-
-  /* This check is useful to know if somewhere the DeviceStorageFile
-     has not been properly set. Mimetype is not checked because it can be
-     empty. */
-  MOZ_ASSERT(aFile->mLength != UINT64_MAX);
-  MOZ_ASSERT(aFile->mLastModifiedDate != UINT64_MAX);
-
-  RefPtr<BlobImpl> blobImpl = new BlobImplFile(fullPath, aFile->mMimeType,
-                                                 aFile->mLength, aFile->mFile,
-                                                 aFile->mLastModifiedDate);
-
-  /* File should start out as mutable by default but we should turn
-     that off if it wasn't requested. */
-  bool editable;
-  nsresult rv = blobImpl->GetMutable(&editable);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    DS_LOG_WARN("%u cannot query mutable", aId);
-    return Reject(aId, POST_ERROR_EVENT_UNKNOWN);
-  }
-
-  if (editable != aFile->mEditable) {
-    rv = blobImpl->SetMutable(aFile->mEditable);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      DS_LOG_WARN("%u cannot set mutable %d", aId, aFile->mEditable);
-      return Reject(aId, POST_ERROR_EVENT_UNKNOWN);
-    }
-  }
-
-  return Resolve(aId, blobImpl, aForceDispatch);
-}
-
-nsresult
-DeviceStorageRequestManager::Resolve(uint32_t aId, BlobImpl* aBlobImpl,
-                                     bool aForceDispatch)
-{
-  if (aForceDispatch || !IsOwningThread()) {
-    DS_LOG_DEBUG("recv %u w/ %p", aId, aBlobImpl);
-    RefPtr<DeviceStorageRequestManager> self = this;
-    RefPtr<BlobImpl> blobImpl = aBlobImpl;
-    nsCOMPtr<nsIRunnable> r
-      = NS_NewRunnableFunction([self, aId, blobImpl] () -> void
-    {
-      self->Resolve(aId, blobImpl, false);
-    });
-    return DispatchOrAbandon(aId, r.forget());
-  }
-
-  DS_LOG_INFO("posted %u w/ %p", aId, aBlobImpl);
-
-  if (NS_WARN_IF(aId == INVALID_ID)) {
-    DS_LOG_ERROR("invalid");
-    MOZ_ASSERT_UNREACHABLE("resolve invalid request");
-    return NS_OK;
-  }
-
-  ListIndex i = Find(aId);
-  if (NS_WARN_IF(i == mPending.Length())) {
-    return NS_OK;
-  }
-
-  if (!aBlobImpl) {
-    return ResolveInternal(i, JS::NullHandleValue);
-  }
-
-  nsIGlobalObject* global = mPending[i].mRequest->GetOwnerGlobal();
-
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(global))) {
-    return RejectInternal(i, NS_LITERAL_STRING(POST_ERROR_EVENT_UNKNOWN));
-  }
-
-  RefPtr<Blob> blob = Blob::Create(global, aBlobImpl);
-  JS::Rooted<JSObject*> obj(jsapi.cx(),
-                            blob->WrapObject(jsapi.cx(), nullptr));
-  MOZ_ASSERT(obj);
-  JS::RootedValue value(jsapi.cx(), JS::ObjectValue(*obj));
-  return ResolveInternal(i, value);
-}
-
-nsresult
-DeviceStorageRequestManager::ResolveInternal(ListIndex aIndex,
-                                             JS::HandleValue aResult)
-{
-  MOZ_ASSERT(IsOwningThread());
-  MOZ_ASSERT(!mShutdown);
-
-  /* Note that we must seize the DOMRequest reference and destroy the entry
-     before calling FireError because it may go straight to the JS code
-     which in term may call back into our code (as observed in Shutdown).
-     The safest thing to do is to ensure the very last thing we do is the
-     DOM call so that there is no inconsistent state. */
-  RefPtr<DOMRequest> request;
-  bool isCursor = mPending[aIndex].mCursor;
-  if (!isCursor || aResult.isUndefined()) {
-    request = mPending[aIndex].mRequest.forget();
-    mPending.RemoveElementAt(aIndex);
-  } else {
-    request = mPending[aIndex].mRequest;
-  }
-
-  if (isCursor) {
-    auto cursor = static_cast<nsDOMDeviceStorageCursor*>(request.get());
-
-    /* Must call it with the right pointer type since the base class does
-       not define FireDone and FireSuccess as virtual. */
-    if (aResult.isUndefined()) {
-      DS_LOG_INFO("cursor complete");
-      cursor->FireDone();
-    } else {
-      DS_LOG_INFO("cursor continue");
-      cursor->FireSuccess(aResult);
-    }
-  } else {
-    DS_LOG_INFO("request complete");
-    request->FireSuccess(aResult);
-  }
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestManager::RejectInternal(DeviceStorageRequestManager::ListIndex aIndex,
-                                            const nsString& aReason)
-{
-  MOZ_ASSERT(IsOwningThread());
-  MOZ_ASSERT(!mShutdown);
-
-  /* Note that we must seize the DOMRequest reference and destroy the entry
-     before calling FireError because it may go straight to the JS code
-     which in term may call back into our code (as observed in Shutdown).
-     The safest thing to do is to ensure the very last thing we do is the
-     DOM call so that there is no inconsistent state. */
-  RefPtr<DOMRequest> request = mPending[aIndex].mRequest.forget();
-  bool isCursor = mPending[aIndex].mCursor;
-  mPending.RemoveElementAt(aIndex);
-
-  if (isCursor) {
-    /* Must call it with the right pointer type since the base class does
-       not define FireError as virtual. */
-    auto cursor = static_cast<nsDOMDeviceStorageCursor*>(request.get());
-    cursor->FireError(aReason);
-  } else {
-    request->FireError(aReason);
-  }
-  return NS_OK;
-}
-
-nsresult
-DeviceStorageRequestManager::Reject(uint32_t aId, const nsString& aReason)
-{
-  DS_LOG_DEBUG("recv %u", aId);
-
-  if (NS_WARN_IF(aId == INVALID_ID)) {
-    DS_LOG_ERROR("invalid");
-    MOZ_ASSERT_UNREACHABLE("reject invalid request");
-    return NS_OK;
-  }
-
-  RefPtr<DeviceStorageRequestManager> self = this;
-  nsString reason = aReason;
-  nsCOMPtr<nsIRunnable> r
-    = NS_NewRunnableFunction([self, aId, reason] () -> void
-  {
-    DS_LOG_INFO("posted %u w/ %s", aId,
-                NS_LossyConvertUTF16toASCII(reason).get());
-
-    ListIndex i = self->Find(aId);
-    if (NS_WARN_IF(i == self->mPending.Length())) {
-      return;
-    }
-
-    self->RejectInternal(i, reason);
-  });
-  return DispatchOrAbandon(aId, r.forget());
-}
-
-nsresult
-DeviceStorageRequestManager::Reject(uint32_t aId, const char* aReason)
-{
-  nsString reason;
-  reason.AssignASCII(aReason);
-  return Reject(aId, reason);
-}
-
-void
-DeviceStorageRequestManager::Shutdown()
-{
-  MOZ_ASSERT(IsOwningThread());
-
-  MutexAutoLock lock(mMutex);
-  mShutdown = true;
-  ListIndex i = mPending.Length();
-  DS_LOG_INFO("pending %zu", i);
-  while (i > 0) {
-    --i;
-    DS_LOG_INFO("terminate %u (%u)", mPending[i].mId, mPending[i].mCursor);
-  }
-  mPending.Clear();
-}
-
-DeviceStorageRequestManager::ListIndex
-DeviceStorageRequestManager::Find(uint32_t aId)
-{
-  MOZ_ASSERT(IsOwningThread());
-  ListIndex i = mPending.Length();
-  while (i > 0) {
-    --i;
-    if (mPending[i].mId == aId) {
-      return i;
-    }
-  }
-  DS_LOG_DEBUG("no id %u", aId);
-  return mPending.Length();
-}
deleted file mode 100644
--- a/dom/devicestorage/nsDeviceStorage.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsDeviceStorage_h
-#define nsDeviceStorage_h
-
-#include "mozilla/Atomics.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
-
-#include "DOMRequest.h"
-#include "DOMCursor.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsDOMClassInfoID.h"
-#include "nsIClassInfo.h"
-#include "nsIDOMWindow.h"
-#include "nsIURI.h"
-#include "nsIPrincipal.h"
-#include "nsString.h"
-#include "nsWeakPtr.h"
-#include "nsIDOMEventListener.h"
-#include "nsIObserver.h"
-#include "nsIStringBundle.h"
-#include "mozilla/Mutex.h"
-#include "prtime.h"
-#include "DeviceStorage.h"
-#include "mozilla/StaticPtr.h"
-
-namespace mozilla {
-class ErrorResult;
-
-namespace dom {
-class BlobImpl;
-class DeviceStorageParams;
-} // namespace dom
-} // namespace mozilla
-
-class nsDOMDeviceStorage;
-class DeviceStorageCursorRequest;
-
-//#define DS_LOGGING 1
-
-#ifdef DS_LOGGING
-// FIXME -- use MOZ_LOG and set to warn by default
-#define DS_LOG_DEBUG(msg, ...)  printf_stderr("[%s:%d] " msg "\n", __func__, __LINE__, ##__VA_ARGS__)
-#define DS_LOG_INFO DS_LOG_DEBUG
-#define DS_LOG_WARN DS_LOG_DEBUG
-#define DS_LOG_ERROR DS_LOG_DEBUG
-#else
-#define DS_LOG_DEBUG(msg, ...)
-#define DS_LOG_INFO(msg, ...)
-#define DS_LOG_WARN(msg, ...)
-#define DS_LOG_ERROR(msg, ...)
-#endif
-
-#define POST_ERROR_EVENT_FILE_EXISTS                 "NoModificationAllowedError"
-#define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST         "NotFoundError"
-#define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE         "TypeMismatchError"
-#define POST_ERROR_EVENT_PERMISSION_DENIED           "SecurityError"
-#define POST_ERROR_EVENT_ILLEGAL_TYPE                "TypeMismatchError"
-#define POST_ERROR_EVENT_UNKNOWN                     "Unknown"
-
-enum DeviceStorageRequestType {
-  DEVICE_STORAGE_REQUEST_READ,
-  DEVICE_STORAGE_REQUEST_WRITE,
-  DEVICE_STORAGE_REQUEST_APPEND,
-  DEVICE_STORAGE_REQUEST_CREATE,
-  DEVICE_STORAGE_REQUEST_DELETE,
-  DEVICE_STORAGE_REQUEST_WATCH,
-  DEVICE_STORAGE_REQUEST_FREE_SPACE,
-  DEVICE_STORAGE_REQUEST_USED_SPACE,
-  DEVICE_STORAGE_REQUEST_AVAILABLE,
-  DEVICE_STORAGE_REQUEST_STATUS,
-  DEVICE_STORAGE_REQUEST_FORMAT,
-  DEVICE_STORAGE_REQUEST_MOUNT,
-  DEVICE_STORAGE_REQUEST_UNMOUNT,
-  DEVICE_STORAGE_REQUEST_CREATEFD,
-  DEVICE_STORAGE_REQUEST_CURSOR
-};
-
-enum DeviceStorageAccessType {
-  DEVICE_STORAGE_ACCESS_READ,
-  DEVICE_STORAGE_ACCESS_WRITE,
-  DEVICE_STORAGE_ACCESS_CREATE,
-  DEVICE_STORAGE_ACCESS_UNDEFINED,
-  DEVICE_STORAGE_ACCESS_COUNT
-};
-
-class DeviceStorageUsedSpaceCache final
-{
-public:
-  static DeviceStorageUsedSpaceCache* CreateOrGet();
-
-  DeviceStorageUsedSpaceCache();
-  ~DeviceStorageUsedSpaceCache();
-
-
-  class InvalidateRunnable final : public mozilla::Runnable
-  {
-    public:
-      InvalidateRunnable(DeviceStorageUsedSpaceCache* aCache, 
-                         const nsAString& aStorageName)
-        : mCache(aCache)
-        , mStorageName(aStorageName) {}
-
-      ~InvalidateRunnable() {}
-
-      NS_IMETHOD Run() override
-      {
-        RefPtr<DeviceStorageUsedSpaceCache::CacheEntry> cacheEntry;
-        cacheEntry = mCache->GetCacheEntry(mStorageName);
-        if (cacheEntry) {
-          cacheEntry->mDirty = true;
-        }
-        return NS_OK;
-      }
-    private:
-      DeviceStorageUsedSpaceCache* mCache;
-      nsString mStorageName;
-  };
-
-  void Invalidate(const nsAString& aStorageName)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    MOZ_ASSERT(mIOThread);
-
-    mIOThread->Dispatch(new InvalidateRunnable(this, aStorageName),
-                        NS_DISPATCH_NORMAL);
-  }
-
-  void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    MOZ_ASSERT(mIOThread);
-
-    mIOThread->Dispatch(mozilla::Move(aRunnable), NS_DISPATCH_NORMAL);
-  }
-
-  nsresult AccumUsedSizes(const nsAString& aStorageName,
-                          uint64_t* aPictureSize, uint64_t* aVideosSize,
-                          uint64_t* aMusicSize, uint64_t* aTotalSize);
-
-  void SetUsedSizes(const nsAString& aStorageName,
-                    uint64_t aPictureSize, uint64_t aVideosSize,
-                    uint64_t aMusicSize, uint64_t aTotalSize);
-
-private:
-  friend class InvalidateRunnable;
-
-  struct CacheEntry
-  {
-    // Technically, this doesn't need to be threadsafe, but the implementation
-    // of the non-thread safe one causes ASSERTS due to the underlying thread
-    // associated with a LazyIdleThread changing from time to time.
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheEntry)
-
-    bool mDirty;
-    nsString mStorageName;
-    int64_t  mFreeBytes;
-    uint64_t mPicturesUsedSize;
-    uint64_t mVideosUsedSize;
-    uint64_t mMusicUsedSize;
-    uint64_t mTotalUsedSize;
-
-  private:
-    ~CacheEntry() {}
-  };
-  already_AddRefed<CacheEntry> GetCacheEntry(const nsAString& aStorageName);
-
-  nsTArray<RefPtr<CacheEntry>> mCacheEntries;
-
-  nsCOMPtr<nsIThread> mIOThread;
-
-  static mozilla::StaticAutoPtr<DeviceStorageUsedSpaceCache> sDeviceStorageUsedSpaceCache;
-};
-
-class DeviceStorageTypeChecker final
-{
-public:
-  static DeviceStorageTypeChecker* CreateOrGet();
-
-  DeviceStorageTypeChecker();
-  ~DeviceStorageTypeChecker();
-
-  void InitFromBundle(nsIStringBundle* aBundle);
-
-  bool Check(const nsAString& aType, mozilla::dom::BlobImpl* aBlob);
-  bool Check(const nsAString& aType, nsIFile* aFile);
-  bool Check(const nsAString& aType, const nsString& aPath);
-  void GetTypeFromFile(nsIFile* aFile, nsAString& aType);
-  void GetTypeFromFileName(const nsAString& aFileName, nsAString& aType);
-  static nsresult GetPermissionForType(const nsAString& aType,
-                                       nsACString& aPermissionResult);
-  static nsresult GetAccessForRequest(const DeviceStorageRequestType aRequestType,
-                                      nsACString& aAccessResult);
-  static nsresult GetAccessForIndex(size_t aAccessIndex, nsACString& aAccessResult);
-  static size_t GetAccessIndexForRequest(const DeviceStorageRequestType aRequestType);
-  static bool IsVolumeBased(const nsAString& aType);
-  static bool IsSharedMediaRoot(const nsAString& aType);
-
-private:
-  nsString mPicturesExtensions;
-  nsString mVideosExtensions;
-  nsString mMusicExtensions;
-
-  static mozilla::StaticAutoPtr<DeviceStorageTypeChecker> sDeviceStorageTypeChecker;
-};
-
-class nsDOMDeviceStorageCursor final
-  : public mozilla::dom::DOMCursor
-{
-public:
-  NS_FORWARD_NSIDOMDOMCURSOR(mozilla::dom::DOMCursor::)
-
-  // DOMCursor
-  virtual void Continue(mozilla::ErrorResult& aRv) override;
-
-  nsDOMDeviceStorageCursor(nsIGlobalObject* aGlobal,
-                           DeviceStorageCursorRequest* aRequest);
-
-  void FireSuccess(JS::Handle<JS::Value> aResult);
-  void FireError(const nsString& aReason);
-  void FireDone();
-
-private:
-  virtual ~nsDOMDeviceStorageCursor();
-
-  bool mOkToCallContinue;
-  RefPtr<DeviceStorageCursorRequest> mRequest;
-};
-
-class DeviceStorageRequestManager final
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DeviceStorageRequestManager)
-
-  static const uint32_t INVALID_ID = 0;
-
-  DeviceStorageRequestManager();
-
-  bool IsOwningThread();
-  nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
-
-  void StorePermission(size_t aAccess, bool aAllow);
-  uint32_t CheckPermission(size_t aAccess);
-
-  /* These must be called on the owning thread context of the device
-     storage object. It will hold onto a device storage reference until
-     all of the pending requests are completed or shutdown is called. */
-  uint32_t Create(nsDOMDeviceStorage* aDeviceStorage,
-                  mozilla::dom::DOMRequest** aRequest);
-  uint32_t Create(nsDOMDeviceStorage* aDeviceStorage,
-                  DeviceStorageCursorRequest* aRequest,
-                  nsDOMDeviceStorageCursor** aCursor);
-
-  /* These may be called from any thread context and post a request
-     to the owning thread to resolve the underlying DOMRequest or
-     DOMCursor. In order to trigger FireDone for a DOMCursor, one
-     should call Resolve with only the request ID. */
-  nsresult Resolve(uint32_t aId, bool aForceDispatch);
-  nsresult Resolve(uint32_t aId, const nsString& aValue, bool aForceDispatch);
-  nsresult Resolve(uint32_t aId, uint64_t aValue, bool aForceDispatch);
-  nsresult Resolve(uint32_t aId, DeviceStorageFile* aValue, bool aForceDispatch);
-  nsresult Resolve(uint32_t aId, mozilla::dom::BlobImpl* aValue, bool aForceDispatch);
-  nsresult Reject(uint32_t aId, const nsString& aReason);
-  nsresult Reject(uint32_t aId, const char* aReason);
-
-  void Shutdown();
-
-private:
-  DeviceStorageRequestManager(const DeviceStorageRequestManager&) = delete;
-  DeviceStorageRequestManager& operator=(const DeviceStorageRequestManager&) = delete;
-
-  struct ListEntry {
-    RefPtr<mozilla::dom::DOMRequest> mRequest;
-    uint32_t mId;
-    bool mCursor;
-  };
-
-  typedef nsTArray<ListEntry> ListType;
-  typedef ListType::index_type ListIndex;
-
-  virtual ~DeviceStorageRequestManager();
-  uint32_t CreateInternal(mozilla::dom::DOMRequest* aRequest, bool aCursor);
-  nsresult ResolveInternal(ListIndex aIndex, JS::HandleValue aResult);
-  nsresult RejectInternal(ListIndex aIndex, const nsString& aReason);
-  nsresult DispatchOrAbandon(uint32_t aId,
-                             already_AddRefed<nsIRunnable>&& aRunnable);
-  ListType::index_type Find(uint32_t aId);
-
-  nsCOMPtr<nsIThread> mOwningThread;
-  ListType mPending; // owning thread or destructor only
-
-  mozilla::Mutex mMutex;
-  uint32_t mPermissionCache[DEVICE_STORAGE_ACCESS_COUNT];
-  bool mShutdown;
-
-  static mozilla::Atomic<uint32_t> sLastRequestId;
-};
-
-class DeviceStorageRequest
-  : public mozilla::Runnable
-{
-protected:
-  DeviceStorageRequest();
-
-public:
-  virtual void Initialize(DeviceStorageRequestManager* aManager,
-                          already_AddRefed<DeviceStorageFile>&& aFile,
-                          uint32_t aRequest);
-
-  virtual void Initialize(DeviceStorageRequestManager* aManager,
-                          already_AddRefed<DeviceStorageFile>&& aFile,
-                          uint32_t aRequest,
-                          mozilla::dom::BlobImpl* aBlob);
-
-  virtual void Initialize(DeviceStorageRequestManager* aManager,
-                          already_AddRefed<DeviceStorageFile>&& aFile,
-                          uint32_t aRequest,
-                          DeviceStorageFileDescriptor* aDSFileDescriptor);
-
-  DeviceStorageAccessType GetAccess() const;
-  void GetStorageType(nsAString& aType) const;
-  DeviceStorageFile* GetFile() const;
-  DeviceStorageFileDescriptor* GetFileDescriptor() const;
-  DeviceStorageRequestManager* GetManager() const;
-
-  uint32_t GetId() const
-  {
-    return mId;
-  }
-
-  void PermissionCacheMissed()
-  {
-    mPermissionCached = false;
-  }
-
-  nsresult Cancel();
-  nsresult Allow();
-
-  nsresult Resolve()
-  {
-    /* Always dispatch an empty resolve because that signals a cursor end
-       and should not be executed directly from the caller's context due
-       to the object potentially getting freed before we return. */
-    uint32_t id = mId;
-    mId = DeviceStorageRequestManager::INVALID_ID;
-    return mManager->Resolve(id, true);
-  }
-
-  template<class T>
-  nsresult Resolve(T aValue)
-  {
-    uint32_t id = mId;
-    if (!mMultipleResolve) {
-      mId = DeviceStorageRequestManager::INVALID_ID;
-    }
-    return mManager->Resolve(id, aValue, ForceDispatch());
-  }
-
-  template<class T>
-  nsresult Reject(T aReason)
-  {
-    uint32_t id = mId;
-    mId = DeviceStorageRequestManager::INVALID_ID;
-    return mManager->Reject(id, aReason);
-  }
-
-protected:
-  bool ForceDispatch() const
-  {
-    return !mSendToParent && mPermissionCached;
-  }
-
-  virtual ~DeviceStorageRequest();
-  virtual nsresult Prepare();
-  virtual nsresult CreateSendParams(mozilla::dom::DeviceStorageParams& aParams);
-  nsresult AllowInternal();
-  nsresult SendToParentProcess();
-
-  RefPtr<DeviceStorageRequestManager> mManager;
-  RefPtr<DeviceStorageFile> mFile;
-  uint32_t mId;
-  RefPtr<mozilla::dom::BlobImpl> mBlob;
-  RefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
-  DeviceStorageAccessType mAccess;
-  bool mSendToParent;
-  bool mUseMainThread;
-  bool mUseStreamTransport;
-  bool mCheckFile;
-  bool mCheckBlob;
-  bool mMultipleResolve;
-  bool mPermissionCached;
-
-private:
-  DeviceStorageRequest(const DeviceStorageRequest&) = delete;
-  DeviceStorageRequest& operator=(const DeviceStorageRequest&) = delete;
-};
-
-class DeviceStorageCursorRequest final
-  : public DeviceStorageRequest
-{
-public:
-  DeviceStorageCursorRequest();
-
-  using DeviceStorageRequest::Initialize;
-
-  virtual void Initialize(DeviceStorageRequestManager* aManager,
-                          already_AddRefed<DeviceStorageFile>&& aFile,
-                          uint32_t aRequest,
-                          PRTime aSince);
-
-  void AddFiles(size_t aSize);
-  void AddFile(already_AddRefed<DeviceStorageFile> aFile);
-  nsresult Continue();
-  NS_IMETHOD Run() override;
-
-protected:
-  virtual ~DeviceStorageCursorRequest()
-  { };
-
-  nsresult SendContinueToParentProcess();
-  nsresult CreateSendParams(mozilla::dom::DeviceStorageParams& aParams) override;
-
-  size_t mIndex;
-  PRTime mSince;
-  nsString mStorageType;
-  nsTArray<RefPtr<DeviceStorageFile> > mFiles;
-};
-
-#endif
deleted file mode 100644
--- a/dom/devicestorage/test/chrome.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-skip-if = os == 'android'
-
-[test_app_permissions.html]
-[test_fs_app_permissions.html]
deleted file mode 100644
--- a/dom/devicestorage/test/devicestorage_common.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-var oldVal = false;
-
-Object.defineProperty(Array.prototype, "remove", {
-  enumerable: false,
-  configurable: false,
-  writable: false,
-  value: function(from, to) {
-    // Array Remove - By John Resig (MIT Licensed)
-    var rest = this.slice((to || from) + 1 || this.length);
-    this.length = from < 0 ? this.length + from : from;
-    return this.push.apply(this, rest);
-  }
-});
-
-function devicestorage_setup(callback) {
-  SimpleTest.waitForExplicitFinish();
-
-  const Cc = SpecialPowers.Cc;
-  const Ci = SpecialPowers.Ci;
-  var directoryService = Cc["@mozilla.org/file/directory_service;1"]
-                           .getService(Ci.nsIProperties);
-  var f = directoryService.get("TmpD", Ci.nsIFile);
-  f.appendRelativePath("device-storage-testing");
-
-  let script = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('remove_testing_directory.js'));
-
-  script.addMessageListener('directory-removed', function listener () {
-    script.removeMessageListener('directory-removed', listener);
-    var prefs = [["device.storage.enabled", true],
-                 ["device.storage.testing", true],
-                 ["device.storage.overrideRootDir", f.path],
-                 ["device.storage.prompt.testing", true]];
-    SpecialPowers.pushPrefEnv({"set": prefs}, callback);
-  });
-}
-
-function getRandomBuffer() {
-  var size = 1024;
-  var buffer = new ArrayBuffer(size);
-  var view = new Uint8Array(buffer);
-  for (var i = 0; i < size; i++) {
-    view[i] = parseInt(Math.random() * 255);
-  }
-  return buffer;
-}
-
-function createRandomBlob(mime) {
-  return blob = new Blob([getRandomBuffer()], {type: mime});
-}
-
-function randomFilename(l) {
-  var set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
-  var result = "";
-  for (var i=0; i<l; i++) {
-    var r = Math.floor(set.length * Math.random());
-    result += set.substring(r, r + 1);
-  }
-  return result;
-}
-
-function reportErrorAndQuit(e) {
-  ok(false, "handleError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function createTestFiles(storage, paths) {
-  function createTestFile(path) {
-    return new Promise(function(resolve, reject) {
-      function addNamed() {
-        var req = storage.addNamed(createRandomBlob("image/png"), path);
-
-        req.onsuccess = function() {
-          ok(true, path + " was created.");
-          resolve();
-        };
-
-        req.onerror = function(e) {
-          ok(false, "Failed to create " + path + ': ' + e.target.error.name);
-          reject();
-        };
-      }
-
-      // Bug 980136. Check if the file exists before we create.
-      var req = storage.get(path);
-
-      req.onsuccess = function() {
-        ok(true, path + " exists. Do not need to create.");
-        resolve();
-      };
-
-      req.onerror = function(e) {
-        ok(true, path + " does not exists: " + e.target.error.name);
-        addNamed();
-      };
-    });
-  }
-
-  var arr = [];
-
-  paths.forEach(function(path) {
-    arr.push(createTestFile(path));
-  });
-
-  return Promise.all(arr);
-}
deleted file mode 100644
--- a/dom/devicestorage/test/mochitest.ini
+++ /dev/null
@@ -1,35 +0,0 @@
-[DEFAULT]
-support-files = devicestorage_common.js
-                remove_testing_directory.js
-
-[test_823965.html]
-# [test_add.html]
-# man, our mime database sucks hard.  followup bug # 788273
-[test_addCorrectType.html]
-[test_available.html]
-[test_basic.html]
-[test_dirs.html]
-# [test_diskSpace.html]
-# Possible race between the time we write a file, and the
-# time it takes to be reflected by statfs().  Bug # 791287
-[test_dotdot.html]
-[test_enumerate.html]
-[test_enumerateMultipleContinue.html]
-[test_enumerateOptions.html]
-[test_freeSpace.html]
-# FileSystem API tests start
-[test_fs_basic.html]
-[test_fs_createDirectory.html]
-[test_fs_get.html]
-[test_fs_getFilesAndDirectories.html]
-[test_fs_remove.html]
-[test_fs_createFile.html]
-[test_fs_appendFile.html]
-# FileSystem API tests end
-[test_lastModificationFilter.html]
-[test_overrideDir.html]
-[test_overwrite.html]
-[test_sanity.html]
-[test_usedSpace.html]
-[test_watch.html]
-[test_watchOther.html]
deleted file mode 100644
--- a/dom/devicestorage/test/remove_testing_directory.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// ensure that the directory we are writing into is empty
-try {
-  var Cc = Components.classes;
-  var Ci = Components.interfaces;
-  var directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
-  var f = directoryService.get("TmpD", Ci.nsIFile);
-  f.appendRelativePath("device-storage-testing");
-  f.remove(true);
-} catch(e) {}
-
-sendAsyncMessage('directory-removed', {});
deleted file mode 100644
--- a/dom/devicestorage/test/test_823965.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=823965
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823965">Mozilla Bug 823965</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-var gFileName = "devicestorage/" + randomFilename(12) + "/hi.png";
-var gData = "My name is Doug Turner (?!?).  My IRC nick is DougT.  I like Maple cookies."
-var gDataBlob = new Blob([gData], {type: 'image/png'});
-
-function getSuccess(e) {
-  var storage = navigator.getDeviceStorage("pictures");
-  ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-
-  ok(e.target.result.name == gFileName, "File name should match");
-  ok(e.target.result.size > 0, "File size be greater than zero");
-  ok(e.target.result.type, "File should have a mime type");
-  ok(e.target.result.lastModifiedDate, "File should have a last modified date");
-
-  var mreq = storage.enumerate();
-  mreq.onsuccess = function() {
-    var storage2 = navigator.getDeviceStorage('music');
-    var dreq = storage2.delete(mreq.result.name);
-    dreq.onerror = function () {
-      ok(true, "The bug has been fixed");
-      SimpleTest.finish();
-    };
-    dreq.onsuccess = function () {
-      ok(false, "The bug has been fixed");
-      SimpleTest.finish();
-    };
-  };
-
-  mreq.onerror = getError;
-}
-
-function getError(e) {
-  ok(false, "getError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function addSuccess(e) {
-
-  var filename = e.target.result;
-  if (filename[0] == "/") {
-    // We got /storageName/prefix/filename
-    // Remove the storageName (this shows up on FirefoxOS)
-    filename = filename.substring(1); // Remove leading slash
-    var slashIndex = filename.indexOf("/");
-    if (slashIndex >= 0) {
-      filename = filename.substring(slashIndex + 1); // Remove storageName
-    }
-  }
-  ok(filename == gFileName, "File name should match");
-  // Since we now have the fully qualified name, change gFileName to that.
-  gFileName = e.target.result;
-
-  var storage = navigator.getDeviceStorage("pictures");
-  request = storage.get(gFileName);
-  request.onsuccess = getSuccess;
-  request.onerror = getError;
-
-  ok(true, "addSuccess was called");
-}
-
-function addError(e) {
-  ok(false, "addError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-
-var storage = navigator.getDeviceStorage("pictures");
-ok(storage, "Should have gotten a storage");
-
-request = storage.addNamed(gDataBlob, gFileName);
-ok(request, "Should have a non-null request");
-
-request.onsuccess = addSuccess;
-request.onerror = addError;
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_add.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=786922
--->
-<head>
-  <title>Test for basic sanity of the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=786922">Mozilla Bug 786922</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-
-devicestorage_setup(function () {
-
-function add(storage, mime) {
-  dump("adding: " + mime + "\n");
-  return navigator.getDeviceStorage(storage).add(createRandomBlob(mime));
-}
-
-var tests = [
-  function () { return add("pictures", "image/png")},
-  function () { return add("videos",   "video/webm")},
-  function () { return add("music",    "audio/wav")},
-  function () { return add("sdcard",   "maple/cookies")},
-];
-
-function fail(e) {
-  ok(false, "onerror was called");
-  SimpleTest.finish();
-}
-
-function next(e) {
-
-  if (e != undefined)
-    ok(true, "addError was called");
-
-  var f = tests.pop();
-
-  if (f == undefined) {
-    SimpleTest.finish();
-    return;
-  }
-
-  request = f();
-  request.onsuccess = next;
-  request.onerror = fail;
-}
-
-next();
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_addCorrectType.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=786922
--->
-<head>
-  <title>Test for basic sanity of the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=786922">Mozilla Bug 786922</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-
-devicestorage_setup(function () {
-
-function addNamed(storage, mime, fileExtension) {
-  dump("adding: " + mime + " " + fileExtension + "\n");
-  return navigator.getDeviceStorage(storage).addNamed(createRandomBlob(mime), randomFilename(40) + "." + fileExtension);
-}
-
-// These tests must all fail
-var tests = [
-  function () { return addNamed("pictures", "kyle/smash", ".png")},
-  function () { return addNamed("pictures", "image/png",  ".poo")},
-  function () { return addNamed("music",    "kyle/smash", ".mp3")},
-  function () { return addNamed("music",    "music/mp3",  ".poo")},
-  function () { return addNamed("videos",   "kyle/smash", ".ogv")},
-  function () { return addNamed("videos",   "video/ogv",  ".poo")},
-];
-
-function fail(e) {
-  ok(false, "addSuccess was called");
-  ok(e.target.error.name == "TypeMismatchError", "Error must be TypeMismatchError");
-
-  SimpleTest.finish();
-}
-
-function next(e) {
-
-  if (e != undefined)
-    ok(true, "addError was called");
-
-  var f = tests.pop();
-
-  if (f == undefined) {
-    SimpleTest.finish();
-    return;
-  }
-
-  request = f();
-  request.onsuccess = fail;
-  request.onerror = next;
-}
-
-next();
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_app_permissions.html
+++ /dev/null
@@ -1,481 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=805322
--->
-<head>
-  <meta charset="utf-8">
-  <title>Permission test for Device Storage</title>
-  <script type="application/javascript"
-           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css"
-         href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
-</head>
-<body>
-<a target="_blank"
-    href="https://bugzilla.mozilla.org/show_bug.cgi?id=805322">Mozilla Bug 805322</a>
-<p id="display"></p>
-<div id="content">
-  
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.7">
-
-function randomFilename(l) {
-  var set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
-  var result = "";
-  for (var i=0; i<l; i++) {
-    var r = Math.floor(set.length * Math.random());
-    result += set.substring(r, r + 1);
-  }
-  return result;
-}
-
-var MockPermissionPrompt = SpecialPowers.MockPermissionPrompt;
-MockPermissionPrompt.init();
-
-SimpleTest.waitForExplicitFinish();
-
-function TestAdd(iframe, data) {
-
-  var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "Should be able to get storage object for " + data.type);
-
-  var blob = new Blob(["Kyle Huey is not a helicopter."], {type: data.mimeType});
-
-  request = storage.addNamed(blob, randomFilename(100) + "hi" + data.fileExtension);
-  isnot(request, null, "Should be able to get request");
-
-  request.onsuccess = function() {
-    is(data.shouldPass, true, "onsuccess was called for type " + data.type);
-    testComplete(iframe, data);
-  };
-
-  request.onerror = function(e) {
-    isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
-    is(e.target.error.name, "SecurityError", "onerror should fire a SecurityError");
-    testComplete(iframe, data);
-  };
-}
-
-function TestGet(iframe, data) {
-
-  createTestFile(data.fileExtension);
-
-  var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "Should be able to get storage object for " + data.type);
-
-  request = storage.get("testfile" + data.fileExtension);
-  isnot(request, null, "Should be able to get request");
-
-  request.onsuccess = function() {
-    is(data.shouldPass, true, "onsuccess was called for type " + data.type);
-    testComplete(iframe, data);
-  };
-
-  request.onerror = function(e) {
-    isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
-    testComplete(iframe, data);
-  };
-}
-
-function TestDelete(iframe, data) {
-
-  createTestFile(data.fileExtension);
-
-  var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "Should be able to get storage object for " + data.type);
-
-  request = storage.delete("testfile" + data.fileExtension);
-  isnot(request, null, "Should be able to get request");
-
-  request.onsuccess = function() {
-    is(data.shouldPass, true, "onsuccess was called for type " + data.type);
-    testComplete(iframe, data);
-  };
-
-  request.onerror = function(e) {
-    isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
-    is(e.target.error.name, "SecurityError", "onerror should fire a SecurityError");
-    testComplete(iframe, data);
-  };
-}
-
-function TestEnumerate(iframe, data) {
-
-  createTestFile(data.fileExtension);
-
-  var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "Should be able to get storage object for " + data.type);
-
-  request = storage.enumerate();
-  isnot(request, null, "Should be able to get request");
-
-  request.onsuccess = function(e) {
-    is(data.shouldPass, true, "onsuccess was called for type " + data.type);
-
-    if (e.target.result == null) {
-      testComplete(iframe, data);
-      return;
-    }
-    e.target.continue();
-  };
-
-  request.onerror = function(e) {
-    isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
-    is(e.target.error.name, "SecurityError", "onerror should fire a SecurityError");
-    testComplete(iframe, data);
-  };
-}
-
-var gTestUri = "https://example.com/chrome/dom/devicestorage/test/test_app_permissions.html"
-
-var gData = [
-
-  // Get
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    shouldPass: false,
-    fileExtension: '.png',
-    test: TestGet
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogv',
-    test: TestGet
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestGet
-  },
-  {
-    type: 'sdcard',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestGet
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    shouldPass: true,
-    fileExtension: '.png',
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestGet
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogv',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestGet
-  },
-  {
-    type: 'music',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:music"],
-
-    test: TestGet
-  },
-  {
-    type: 'sdcard',
-    shouldPass: true,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestGet
-  },
-
-
-  // Add
-
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    mimeType: 'image/png',
-    fileExtension: '.png',
-    shouldPass: false,
-    test: TestAdd
-  },
-  {
-    type: 'videos',
-    mimeType: 'video/ogv',
-    fileExtension: '.ogv',
-    shouldPass: false,
-    test: TestAdd
-  },
-  {
-    type: 'music',
-    mimeType: 'audio/ogg',
-    fileExtension: '.ogg',
-    shouldPass: false,
-    test: TestAdd
-  },
-  {
-    type: 'sdcard',
-    mimeType: 'text/plain',
-    fileExtension: '.txt',
-    shouldPass: false,
-    test: TestAdd
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    mimeType: 'image/png',
-    fileExtension: '.png',
-    shouldPass: true,
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestAdd
-  },
-  {
-    type: 'videos',
-    mimeType: 'video/ogv',
-    fileExtension: '.ogv',
-    shouldPass: true,
-
-    permissions: ["device-storage:videos"],
-
-    test: TestAdd
-  },
-  {
-    type: 'music',
-    mimeType: 'audio/ogg',
-    fileExtension: '.ogg',
-    shouldPass: true,
-
-    permissions: ["device-storage:music"],
-
-    test: TestAdd
-  },
-  {
-    type: 'sdcard',
-    mimeType: 'text/plain',
-    fileExtension: '.txt',
-    shouldPass: true,
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestAdd
-  },
-
-
-// Delete 
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    shouldPass: false,
-    fileExtension: '.png',
-    test: TestDelete
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogv',
-    test: TestDelete
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestDelete
-  },
-  {
-    type: 'sdcard',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestDelete
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    shouldPass: true,
-    fileExtension: '.png',
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestDelete
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogv',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestDelete
-  },
-  {
-    type: 'music',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:music"],
-
-    test: TestDelete
-  },
-  {
-    type: 'sdcard',
-    shouldPass: true,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestDelete
-  },
-
-// Enumeration 
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    shouldPass: false,
-    fileExtension: '.png',
-    test: TestEnumerate
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogv',
-    test: TestEnumerate
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestEnumerate
-  },
-  {
-    type: 'sdcard',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestEnumerate
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    shouldPass: true,
-    fileExtension: '.png',
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestEnumerate
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogv',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestEnumerate
-  },
-  {
-    type: 'music',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:music"],
-
-    test: TestEnumerate
-  },
-  {
-    type: 'sdcard',
-    shouldPass: true,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestEnumerate
-  },
-
-];
-
-function setupTest(iframe,data) {
-  if (data.permissions) {
-    for (var j in data.permissions) {
-      SpecialPowers.addPermission(data.permissions[j], true, iframe.contentDocument);
-    }
-  }
-}
-
-function testComplete(iframe, data) {
-  if (data.permissions) {
-    for (var j in data.permissions) {
-      SpecialPowers.removePermission(data.permissions[j], iframe.contentDocument);
-    }
-  }
-  
-  document.getElementById('content').removeChild(iframe);
-
-  if (gData.length == 0) {
-    SimpleTest.finish();
-  } else {
-    gTestRunner.next();
-  }
-}
-
-function* runTest() {
-  while (gData.length > 0) {
-    var iframe = document.createElement('iframe');
-    var data = gData.pop();
-
-    iframe.setAttribute('mozbrowser', '');
-
-    iframe.src = gTestUri;
-
-    iframe.addEventListener('load', function(e) {
-      setupTest(iframe, data)
-      data.test(iframe, data);
-    });
-
-    document.getElementById('content').appendChild(iframe);
-    yield undefined;
-  }
-}
-
-function createTestFile(extension) {
-try {
-  const Cc = SpecialPowers.Cc;
-  const Ci = SpecialPowers.Ci;
-  var directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
-  var f = directoryService.get("TmpD", Ci.nsIFile);
-  f.appendRelativePath("device-storage-testing");
-  f.remove(true);
-  f.appendRelativePath("testfile" + extension);
-  f.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
-  } catch(e) {}
-}
-
-createTestFile('.txt');
-var gTestRunner = runTest();
-SpecialPowers.addPermission("browser", true, gTestUri);
-
-SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
-                                   ["network.disable.ipc.security", true],
-                                   ["device.storage.enabled", true],
-                                   ["device.storage.testing", true],
-                                   ["device.storage.prompt.testing", false]]},
-  function() {  gTestRunner.next(); });
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_available.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=834595
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=834595">Mozilla Bug 834595</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-function availableSuccess(e) {
-  isnot(e.target.result, null, "result should not be null");
-  SimpleTest.finish();
-}
-
-function availableError(e) {
-  ok(false, "availableError was called");
-  SimpleTest.finish();
-}
-
-var storage = navigator.getDeviceStorage("pictures");
-
-request = storage.available();
-ok(request, "Should have a non-null request");
-
-request.onsuccess = availableSuccess;
-request.onerror = availableError;
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_basic.html
+++ /dev/null
@@ -1,141 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function() {
-
-var gFileName = "devicestorage/" + randomFilename(12) + "/hi.png";
-var gData = "My name is Doug Turner.  My IRC nick is DougT.  I like Maple cookies."
-var gDataBlob = new Blob([gData], {type: 'image/png'});
-var gFileReader = new FileReader();
-
-function getAfterDeleteSuccess(e) {
-  ok(false, "file was deleted not successfully");
-  SimpleTest.finish();
-}
-
-function getAfterDeleteError(e) {
-  ok(true, "file was deleted successfully");
-  SimpleTest.finish();
-}
-
-function deleteSuccess(e) {
-
-  ok(e.target.result == gFileName, "File name should match");
-  dump(e.target.result + "\n")
-
-  var storage = navigator.getDeviceStorage("pictures");
-  request = storage.get(e.target.result);
-  request.onsuccess = getAfterDeleteSuccess;
-  request.onerror = getAfterDeleteError;
-
-}
-
-function deleteError(e) {
-  ok(false, "deleteError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function getSuccess(e) {
-  var storage = navigator.getDeviceStorage("pictures");
-  ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-
-  ok(e.target.result.name == gFileName, "File name should match");
-  ok(e.target.result.size > 0, "File size be greater than zero");
-  ok(e.target.result.type, "File should have a mime type");
-  ok(e.target.result.lastModifiedDate, "File should have a last modified date");
-
-  var name = e.target.result.name;
-
-  gFileReader.readAsArrayBuffer(gDataBlob);
-  gFileReader.onload = function(e) {
-    readerCallback(e);
-
-    request = storage.delete(name)
-    request.onsuccess = deleteSuccess;
-    request.onerror = deleteError;
-  }
-}
-
-function readerCallback(e) {
-
-  ab = e.target.result;
-
-  is(ab.byteLength, gData.length, "wrong arraybuffer byteLength");
-  var u8v = new Uint8Array(ab);
-  is(String.fromCharCode.apply(String, u8v), gData, "wrong values");
-}
-
-function getError(e) {
-  ok(false, "getError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function addSuccess(e) {
-
-  var filename = e.target.result;
-  if (filename[0] == "/") {
-    // We got /storageName/prefix/filename
-    // Remove the storageName (this shows up on FirefoxOS)
-    filename = filename.substring(1); // Remove leading slash
-    var slashIndex = filename.indexOf("/");
-    if (slashIndex >= 0) {
-      filename = filename.substring(slashIndex + 1); // Remove storageName
-    }
-  }
-  ok(filename == gFileName, "File name should match");
-
-  // Update gFileName to be the fully qualified name so that
-  // further checks will pass.
-  gFileName = e.target.result;
-
-  var storage = navigator.getDeviceStorage("pictures");
-  request = storage.get(gFileName);
-  request.onsuccess = getSuccess;
-  request.onerror = getError;
-
-  ok(true, "addSuccess was called");
-}
-
-function addError(e) {
-  ok(false, "addError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-
-var storage = navigator.getDeviceStorage("pictures");
-ok(storage, "Should have gotten a storage");
-
-request = storage.addNamed(gDataBlob, gFileName);
-ok(request, "Should have a non-null request");
-
-request.onsuccess = addSuccess;
-request.onerror = addError;
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_dirs.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=886627
--->
-<head>
-  <title>Test for the device storage API</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=886627">
-    Mozilla Bug 886627
-  </a>
-  <p id="display"></p>
-  <div id="content" style="display: none"></div>
-  <pre id="test">
-  <script class="testbody" type="text/javascript">
-
-/**
- * Test that common device storage directories are available.
- *
- * This test differs from other device storage tests in that other tests use a
- * "testing mode", which relocates the device storage directories to a testing
- * directory. On the other hand, this test turns off testing mode to makes sure
- * that the normal, non-testing directories also work properly.
- */
-
-SimpleTest.waitForExplicitFinish();
-
-SpecialPowers.pushPrefEnv({
-  'set': [
-    ["device.storage.enabled", true],
-    ["device.storage.testing", false],
-    ["device.storage.prompt.testing", true],
-  ]
-}, function() {
-  ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-  ok(!navigator.getDeviceStorage("nonexistent-type"), "Should not have nonexistent storage");
-
-  ok(navigator.getDeviceStorage("pictures"), "Should have pictures storage");
-  ok(navigator.getDeviceStorage("videos"), "Should have videos storage");
-  ok(navigator.getDeviceStorage("music"), "Should have music storage");
-
-  // Need special permission to access "apps". We always have the permission in B2G
-  // mochitests, but on other platforms, we need to manually add the permission.
-  var needAppsPermission = false;;
-  if (!SpecialPowers.testPermission(
-      "webapps-manage", SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document)) {
-    ok(!navigator.getDeviceStorage("apps"), "Should not have apps storage without permission");
-    needAppsPermission = true;
-  }
-
-  var testFunction = function() {
-    ok(navigator.getDeviceStorage("apps"), "Should have apps storage with permission");
-    ok(navigator.getDeviceStorage("sdcard"), "Should have sdcard storage");
-    ok(navigator.getDeviceStorage("crashes"), "Should have crashes storage");
-    // The test harness reverts our pref changes automatically.
-    SimpleTest.finish();
-  }
-
-  if (needAppsPermission) {
-    SpecialPowers.pushPermissions(
-      [{ "type":"webapps-manage", "allow": true, "context": document }],
-      testFunction);
-  } else {
-    testFunction();
-  }
-});
-
-  </script>
-  </pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/devicestorage/test/test_diskSpace.html
+++ /dev/null
@@ -1,101 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-var freeBytes = -1;
-var stats = 0;
-
-function stat(s, file_list_length) {
-  if (freeBytes == -1) {
-    freeBytes = s.target.result.freeBytes;
-  }
-
-  ok(freeBytes == s.target.result.freeBytes, "Free bytes should be the same");
-  ok(file_list_length * 1024 == s.target.result.totalBytes, "space taken up by files should match")
-
-  stats = stats + 1;
-
-  if (stats == 2) {
-    SimpleTest.finish();
-  }
-}
-
-function addSuccess(e) {
-  added = added - 1;
-
-  if (added == 0) {
-    request = pictures.stat();
-    request.onsuccess = function(s) {stat(s, picture_files.length)};
-
-    request = videos.stat();
-    request.onsuccess = function(s) {stat(s, video_files.length)};
-
-    request = music.stat();
-    request.onsuccess = function(s) {stat(s, music_files.length)};
-  }
-}
-
-function addError(e) {
-  ok(false, "addError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-ok(true, "hi");
-
-var pictures = navigator.getDeviceStorage("pictures");
-var picture_files = [ "a.png", "b.png", "c.png", "d.png", "e.png" ];
-
-var videos = navigator.getDeviceStorage("videos");
-var video_files = [ "a.ogv", "b.ogv" ];
-
-var music = navigator.getDeviceStorage("music");
-var music_files = [ "a.mp3", "b.mp3", "c.mp3" ];
-
-var added = picture_files.length + video_files.length + music_files.length;
-
-for (var i=0; i < picture_files.length; i++) {
- request = pictures.addNamed(createRandomBlob('image/png'), picture_files[i]);
- request.onsuccess = addSuccess;
- request.onerror = addError;
-}
-
-for (var i=0; i < video_files.length; i++) {
- request = videos.addNamed(createRandomBlob('video/ogv'), video_files[i]);
- request.onsuccess = addSuccess;
- request.onerror = addError;
-}
-
-for (var i=0; i < music_files.length; i++) {
- request = music.addNamed(createRandomBlob('audio/mp3'), music_files[i]);
- request.onsuccess = addSuccess;
- request.onerror = addError;
-}
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_dotdot.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-function testingStorage() {
-  return navigator.getDeviceStorage("pictures");
-}
-
-var tests = [
-  function () { return testingStorage().addNamed(createRandomBlob('image/png'), gFileName); },
-  function () { return testingStorage().delete(gFileName); },
-  function () { return testingStorage().get(gFileName); },
-  function () { var r = testingStorage().enumerate("../"); return r; }
-];
-
-var gFileName = "../owned.png";
-
-function fail(e) {
-  ok(false, "addSuccess was called");
-  dump(request);
-  SimpleTest.finish();
-}
-
-function next(e) {
-
-  if (e != undefined) {
-    ok(true, "addError was called");
-    ok(e.target.error.name == "SecurityError", "Error must be SecurityError");
-  }
-
-  var f = tests.pop();
-
-  if (f == undefined) {
-    SimpleTest.finish();
-    return;
-  }
-
-  request = f();
-  request.onsuccess = fail;
-  request.onerror = next;
-}
-
-next();
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_enumerate.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-function enumerateSuccess(e) {
-
-  if (e.target.result == null) {
-    ok(files.length == 0, "when the enumeration is done, we shouldn't have any files in this array")
-    dump("We still have length = " + files.length + "\n");
-    SimpleTest.finish();
-    return;
-  }
-
-  var filename = e.target.result.name;
-  if (filename[0] == "/") {
-    // We got /storageName/prefix/filename
-    // Remove the storageName (this shows up on FirefoxOS)
-    filename = filename.substring(1); // Remove leading slash
-    var slashIndex = filename.indexOf("/");
-    if (slashIndex >= 0) {
-      filename = filename.substring(slashIndex + 1); // Remove storageName
-    }
-  }
-  if (filename.startsWith(prefix)) {
-    filename = filename.substring(prefix.length + 1); // Remove prefix
-  }
-
-  var index = files.indexOf(filename);
-  files.remove(index);
-
-  ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
-
-  // clean up
-  var cleanup = storage.delete(e.target.result.name);
-  cleanup.onsuccess = function(e) {}  // todo - can i remove this?
-
-  e.target.continue();
-}
-
-function handleError(e) {
-  ok(false, "handleError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function addSuccess(e) {
-  addedSoFar = addedSoFar + 1;
-  if (addedSoFar == files.length) {
-
-    var cursor = storage.enumerate(prefix);
-    cursor.onsuccess = enumerateSuccess;
-    cursor.onerror = handleError;
-  }
-}
-
-function addError(e) {
-  ok(false, "addError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-var storage = navigator.getDeviceStorage("pictures");
-ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-var prefix = "devicestorage/" + randomFilename(12) + ".png"
-
-var files = [ "a.PNG", "b.pnG", "c.png", "d/a.png", "d/b.png", "d/c.png", "d/d.png", "The/quick/brown/fox/jumps/over/the/lazy/dog.png"]
-var addedSoFar = 0;
-
-
-for (var i=0; i<files.length; i++) {
-
- request = storage.addNamed(createRandomBlob('image/png'), prefix + '/' + files[i]);
-
- ok(request, "Should have a non-null request");
- request.onsuccess = addSuccess;
- request.onerror = addError;
-}
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_enumerateMultipleContinue.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-function enumerateSuccess(e) {
-}
-
-function enumerateFailure(e) {
-}
-
-var cursor = navigator.getDeviceStorage("pictures").enumerate();
-cursor.onsuccess = enumerateSuccess;
-cursor.onerror = enumerateFailure;
-
-try {
- cursor.continue();
-}
-catch (e) {
-  ok(true, "Calling continue before enumerateSuccess fires should throw");
-  SimpleTest.finish();
-}
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_enumerateNoParam.html
+++ /dev/null
@@ -1,109 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-  
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-// Array Remove - By John Resig (MIT Licensed)
-Array.prototype.remove = function(from, to) {
-  var rest = this.slice((to || from) + 1 || this.length);
-  this.length = from < 0 ? this.length + from : from;
-  return this.push.apply(this, rest);
-};
-
-devicestorage_setup();
-
-function enumerateSuccess(e) {
-
-  if (e.target.result == null) {
-    ok(files.length == 0, "when the enumeration is done, we shouldn't have any files in this array")
-    SimpleTest.finish();
-    return;
-  }
-  
-  var filename = e.target.result.name;
-  if (filename[0] == "/") {
-    // We got /storageName/prefix/filename
-    // Remove the storageName (this shows up on FirefoxOS)
-    filename = filename.substring(1); // Remove leading slash
-    var slashIndex = filename.indexOf("/");
-    if (slashIndex >= 0) {
-      filename = filename.substring(slashIndex + 1); // Remove storageName
-    }
-  }
-  if (filename.startsWith(prefix)) {
-    filename = filename.substring(prefix.length + 1); // Remove prefix
-  }
-
-  var index = files.indexOf(enumFilename);
-  files.remove(index);
-
-  ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
-
-  // clean up
-  var cleanup = storage.delete(e.target.result.name);
-  cleanup.onsuccess = function(e) {}  // todo - can i remove this?
-
-  e.target.continue();
-}
-
-function handleError(e) {
-  ok(false, "handleError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function addSuccess(e) {
-  addedSoFar = addedSoFar + 1;
-  if (addedSoFar == files.length) {
-
-    var cursor = storage.enumerate();
-    cursor.onsuccess = enumerateSuccess;
-    cursor.onerror = handleError;
-  }
-}
-
-function addError(e) {
-  ok(false, "addError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-var storage = navigator.getDeviceStorage("pictures");
-ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
-var prefix = "devicestorage/" + randomFilename(12)
-
-var files = [ "a.png", "b.png", "c.png" ]
-var addedSoFar = 0;
-
-
-for (var i=0; i<files.length; i++) {
-
- request = storage.addNamed(createRandomBlob('image/png'), prefix + '/' + files[i]);
-
- ok(request, "Should have a non-null request");
- request.onsuccess = addSuccess;
- request.onerror = addError;
-}
-
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/devicestorage/test/test_enumerateOptions.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for basic sanity of the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-storage = navigator.getDeviceStorage("pictures");
-
-
-throws = false;
-try {
-var cursor = storage.enumerate();
-} catch(e) {throws = true}
-ok(!throws, "enumerate no parameter");
-
-throws = false;
-try {
-var cursor = storage.enumerate("string");
-} catch(e) {throws = true}
-ok(!throws, "enumerate one string parameter");
-
-throws = false;
-try {
-var cursor = storage.enumerate("string", "string2");
-} catch(e) {throws = true}
-ok(throws, "enumerate two string parameter");
-
-throws = false;
-try {
-var cursor = storage.enumerate("string", {"since": new Date(1)});
-} catch(e) {throws = true}
-ok(!throws, "enumerate a string and object parameter");
-
-throws = false;
-try {
-var cursor = storage.enumerate({"path": "a"});
-} catch(e) {throws = true}
-ok(!throws, "enumerate object parameter with path");
-
-throws = false;
-try {
-var cursor = storage.enumerate({}, "string");
-} catch(e) {throws = true}
-ok(throws, "enumerate object then a string");
-
-throws = false;
-try {
-var cursor = storage.enumerate({"path": "a", "since": new Date(0) });
-} catch(e) {throws = true}
-ok(!throws, "enumerate object parameter with path");
-
-SimpleTest.finish()
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_freeSpace.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html> <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=717103
--->
-<head>
-  <title>Test for the device storage API </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="devicestorage_common.js"></script>
-
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-devicestorage_setup(function () {
-
-function freeSpaceSuccess(e) {
-  ok(e.target.result  > 0, "free bytes should exist and be greater than zero");
-  SimpleTest.finish();
-}
-
-function freeSpaceError(e) {
-  ok(false, "freeSpaceError was called");
-  SimpleTest.finish();
-}
-
-var storage = navigator.getDeviceStorage("pictures");
-
-function addError(e) {
-  ok(false, "addError was called : " + e.target.error.name);
-  SimpleTest.finish();
-}
-
-function addSuccess(e) {
-  request = storage.freeSpace();
-  ok(request, "Should have a non-null request");
-
-  request.onsuccess = freeSpaceSuccess;
-  request.onerror = freeSpaceError;
-}
-
-var prefix = "devicestorage/" + randomFilename(12);
-request = storage.addNamed(createRandomBlob('image/png'), prefix + "/a/b.png");
-request.onsuccess = addSuccess;
-request.onerror = addError;
-
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/devicestorage/test/test_fs_app_permissions.html
+++ /dev/null
@@ -1,598 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=910412
--->
-<head>
-  <meta charset="utf-8">
-  <title>Permission test of FileSystem API for Device Storage</title>
-  <script type="application/javascript"
-           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css"
-         href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
-</head>
-<body>
-<a target="_blank"
-    href="https://bugzilla.mozilla.org/show_bug.cgi?id=910412">Mozilla Bug 910412</a>
-<p id="display"></p>
-<div id="content">
-
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.7">
-
-function randomFilename(l) {
-  let set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
-  let result = "";
-  for (let i=0; i<l; i++) {
-    let r = Math.floor(set.length * Math.random());
-    result += set.substring(r, r + 1);
-  }
-  return result;
-}
-
-function getRandomBuffer() {
-  var size = 1024;
-  var buffer = new ArrayBuffer(size);
-  var view = new Uint8Array(buffer);
-  for (var i = 0; i < size; i++) {
-    view[i] = parseInt(Math.random() * 255);
-  }
-  return buffer;
-}
-
-function createRandomBlob(mime) {
-  let size = 1024;
-  let buffer = new ArrayBuffer(size);
-  let view = new Uint8Array(buffer);
-  for (let i = 0; i < size; i++) {
-    view[i] = parseInt(Math.random() * 255);
-  }
-  return blob = new Blob([buffer], {type: mime});
-}
-
-let MockPermissionPrompt = SpecialPowers.MockPermissionPrompt;
-MockPermissionPrompt.init();
-
-SimpleTest.waitForExplicitFinish();
-
-function TestCreateDirectory(iframe, data) {
-  function cbError(e) {
-    is(e.name, "SecurityError", "[TestCreateDirectory] Should fire a SecurityError for type " + data.type);
-    is(data.shouldPass, false, "[TestCreateDirectory] Error callback was called for type " + data.type + '. Error: ' + e.name);
-    testComplete(iframe, data);
-  }
-
-  let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "[TestCreateDirectory] Should be able to get storage object for " + data.type);
-
-  if (!storage) {
-    testComplete(iframe, data);
-    return;
-  }
-
-  storage.getRoot().then(function(root) {
-    is(data.shouldPass, true, "[TestCreateDirectory] Success callback was called for type " + data.type);
-    let filename = randomFilename(100);
-    root.createDirectory(filename).then(function(d) {
-      let passed = d && (d.name === filename);
-      is(data.shouldPass, passed, "[TestCreateDirectory] Success callback was called for type " + data.type);
-      testComplete(iframe, data);
-    }, cbError);
-  }, cbError);
-}
-
-function TestGet(iframe, data) {
-  function cbError(e) {
-    is(e.name, "SecurityError", "[TestGet] Should fire a SecurityError for type " + data.type);
-    is(data.shouldPass, false, "[TestGet] Error callback was called for type " + data.type + '. Error: ' + e.name);
-    testComplete(iframe, data);
-  }
-
-  createTestFile(data.fileExtension);
-
-  let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "[TestGet] Should be able to get storage object for " + data.type);
-
-  if (!storage) {
-    testComplete(iframe, data);
-    return;
-  }
-
-  storage.getRoot().then(function(root) {
-    ok(true, "[TestGet] Success callback of getRoot was called for type " + data.type);
-    root.get("testfile" + data.fileExtension).then(function() {
-      is(data.shouldPass, true, "[TestGet] Success callback was called for type " + data.type);
-      testComplete(iframe, data);
-    }, cbError);
-  }, cbError);
-}
-
-function TestCreateFile(iframe, data) {
-  function cbError(e) {
-    is(e.name, "SecurityError", "[TestCreateFile] Should fire a SecurityError for type " + data.type);
-    is(data.shouldPass, false, "[TestCreateFile] Error callback was called for type " + data.type + '. Error: ' + e.name);
-    testComplete(iframe, data);
-  }
-
-  let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "[TestCreateFile] Should be able to get storage object for " + data.type);
-
-  if (!storage) {
-    testComplete(iframe, data);
-    return;
-  }
-
-  storage.getRoot().then(function(root) {
-    ok(true, "[TestCreateFile] Success callback of getRoot was called for type " + data.type);
-    let filename = randomFilename(100) + data.fileExtension;
-    root.createFile(filename, {
-      data: createRandomBlob(data.mimeType),
-      ifExists: "replace"
-    }).then(function() {
-      is(data.shouldPass, true, "[TestCreateFile] Success callback was called for type " + data.type);
-      testComplete(iframe, data);
-    }, cbError);
-  }, cbError);
-}
-
-function TestRemove(iframe, data) {
-  function cbError(e) {
-    is(e.name, "SecurityError", "[TestRemove] Should fire a SecurityError for type " + data.type);
-    is(data.shouldPass, false, "[TestRemove] Error callback was called for type " + data.type + '. Error: ' + e.name);
-    testComplete(iframe, data);
-  }
-
-  createTestFile(data.fileExtension);
-
-  let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
-  isnot(storage, null, "[TestRemove] Should be able to get storage object for " + data.type);
-
-  if (!storage) {
-    testComplete(iframe, data);
-    return;
-  }
-
-  storage.getRoot().then(function(root) {
-    ok(true, "[TestRemove] Success callback of getRoot was called for type " + data.type);
-    root.remove("testfile" + data.fileExtension).then(function() {
-      is(data.shouldPass, true, "[TestRemove] Success callback was called for type " + data.type);
-      testComplete(iframe, data);
-    }, cbError);
-  }, cbError);
-}
-
-let gTestUri = "https://example.com/tests/dom/devicestorage/test/test_fs_app_permissions.html"
-
-let gData = [
-
-  // Directory#get
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    shouldPass: false,
-    fileExtension: '.png',
-    test: TestGet
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogv',
-    test: TestGet
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestGet
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestGet
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestGet
-  },
-  {
-    type: 'sdcard',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestGet
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    shouldPass: true,
-    fileExtension: '.png',
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestGet
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogv',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestGet
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestGet
-  },
-  {
-    type: 'music',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:music"],
-
-    test: TestGet
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:music"],
-
-    test: TestGet
-  },
-  {
-    type: 'sdcard',
-    shouldPass: true,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestGet
-  },
-
-  // Directory#createDirectory
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    shouldPass: false,
-    test: TestCreateDirectory
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    test: TestCreateDirectory
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    test: TestCreateDirectory
-  },
-  {
-    type: 'sdcard',
-    shouldPass: false,
-    test: TestCreateDirectory
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    shouldPass: true,
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestCreateDirectory
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-
-    permissions: ["device-storage:videos"],
-
-    test: TestCreateDirectory
-  },
-  {
-    type: 'music',
-    shouldPass: true,
-
-    permissions: ["device-storage:music"],
-
-    test: TestCreateDirectory
-  },
-  {
-    type: 'sdcard',
-    shouldPass: true,
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestCreateDirectory
-  },
-
-  // Directory#createFile
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    mimeType: 'image/png',
-    shouldPass: false,
-    fileExtension: '.png',
-    test: TestCreateFile
-  },
-  {
-    type: 'videos',
-    mimeType: 'video/ogv',
-    shouldPass: false,
-    fileExtension: '.ogv',
-    test: TestCreateFile
-  },
-  {
-    type: 'videos',
-    mimeType: 'video/ogg',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestCreateFile
-  },
-  {
-    type: 'music',
-    mimeType: 'audio/ogg',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestCreateFile
-  },
-  {
-    type: 'music',
-    mimeType: 'audio/ogg',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestCreateFile
-  },
-  {
-    type: 'sdcard',
-    mimeType: 'text/plain',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestCreateFile
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    mimeType: 'image/png',
-    shouldPass: true,
-    fileExtension: '.png',
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestCreateFile
-  },
-  {
-    type: 'videos',
-    mimeType: 'video/ogv',
-    shouldPass: true,
-    fileExtension: '.ogv',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestCreateFile
-  },
-  {
-    type: 'videos',
-    mimeType: 'video/ogg',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestCreateFile
-  },
-  {
-    type: 'music',
-    mimeType: 'audio/ogg',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:music"],
-
-    test: TestCreateFile
-  },
-  {
-    type: 'music',
-    mimeType: 'audio/ogg',
-    shouldPass: false,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:music"],
-
-    test: TestCreateFile
-  },
-  {
-    type: 'sdcard',
-    mimeType: 'text/plain',
-    shouldPass: true,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestCreateFile
-  },
-
-  // Directory#remove
-
-  // Web applications with no permissions
-  {
-    type: 'pictures',
-    shouldPass: false,
-    fileExtension: '.png',
-    test: TestRemove
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogv',
-    test: TestRemove
-  },
-  {
-    type: 'videos',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestRemove
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.ogg',
-    test: TestRemove
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestRemove
-  },
-  {
-    type: 'sdcard',
-    shouldPass: false,
-    fileExtension: '.txt',
-    test: TestRemove
-  },
-
-  // Web applications with permission granted
-  {
-    type: 'pictures',
-    shouldPass: true,
-    fileExtension: '.png',
-
-    permissions: ["device-storage:pictures"],
-
-    test: TestRemove
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogv',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestRemove
-  },
-  {
-    type: 'videos',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:videos"],
-
-    test: TestRemove
-  },
-  {
-    type: 'music',
-    shouldPass: true,
-    fileExtension: '.ogg',
-
-    permissions: ["device-storage:music"],
-
-    test: TestRemove
-  },
-  {
-    type: 'music',
-    shouldPass: false,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:music"],
-
-    test: TestRemove
-  },
-  {
-    type: 'sdcard',
-    shouldPass: true,
-    fileExtension: '.txt',
-
-    permissions: ["device-storage:sdcard"],
-
-    test: TestRemove
-  },
-
-];
-
-function setupTest(iframe,data) {
-  if (data.permissions) {
-    for (let j in data.permissions) {
-      SpecialPowers.addPermission(data.permissions[j], true, iframe.contentDocument);
-    }
-  }
-}
-
-function testComplete(iframe, data) {
-  if (data.permissions) {
-    for (let j in data.permissions) {
-      SpecialPowers.removePermission(data.permissions[j], iframe.contentDocument);
-    }
-  }
-
-  document.getElementById('content').removeChild(iframe);
-
-  if (gData.length == 0) {
-    SimpleTest.finish();
-  } else {
-    gTestRunner.next();
-  }
-}
-
-function* runTest() {
-  while (gData.length > 0) {
-    let iframe = document.createElement('iframe');
-    let data = gData.shift();
-
-    iframe.setAttribute('mozbrowser', '');
-
-    iframe.src = gTestUri;
-
-    iframe.addEventListener('load', function(e) {
-      setupTest(iframe, data)
-      data.test(iframe, data);
-    });
-
-    document.getElementById('content').appendChild(iframe);
-    yield undefined;
-  }
-}
-
-function createTestFile(extension) {
-  try {
-    const Cc = SpecialPowers.Cc;
-    const Ci = SpecialPowers.Ci;
-    let directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
<