Bug 1299500 - Get rid of DeviceStorage API - part 10 - DeviceStorage, r=ehsan, r=billm
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 08 Mar 2017 20:15:45 +0100
changeset 346584 6d0ea58121800a09bec9acb208649a38695bec7d
parent 346583 3364716e5765cfe44b16cb1d25c5a9ed43b8b45f
child 346585 c539b2e9f9c926c73809deaaf66289c20147e191
push id87844
push useramarchesini@mozilla.com
push dateWed, 08 Mar 2017 19:31:23 +0000
treeherdermozilla-inbound@c539b2e9f9c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, billm
bugs1299500
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1299500 - Get rid of DeviceStorage API - part 10 - DeviceStorage, r=ehsan, r=billm
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/tests/mochitest/general/test_interfaces.js
dom/webidl/DeviceStorage.webidl
dom/webidl/moz.build
ipc/ipdl/sync-messages.ini
layout/build/nsLayoutStatics.cpp
mobile/android/components/ContentPermissionPrompt.js
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
mobile/android/locales/en-US/chrome/browser.properties
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
@@ -84,48 +84,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
@@ -302,21 +302,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/FileBlobImpl.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 FileBlobImpl(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,45 +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/.
-
-with Files("**"):
-    BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
-
-
-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,4139 +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/FileBlobImpl.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 "nsIInputStream.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 FileBlobImpl(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">
-
-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">
-
-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',
-
-    per