Bug 1263992 - patch 1 - Remove DirectoryType enum, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 18 Apr 2016 03:32:30 -0400
changeset 331428 e41a5ba6a469bee3ef88216ead0a19b8f17a71e3
parent 331427 5bf181aae1ad9aba0ec64a4e0b6d5ab23476562c
child 331429 d03c5ce224dde1d32d7d2de7b44a7314df76e21d
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1263992
milestone48.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 1263992 - patch 1 - Remove DirectoryType enum, r=smaug
dom/base/StructuredCloneHolder.cpp
dom/filesystem/CreateDirectoryTask.cpp
dom/filesystem/DeviceStorageFileSystem.cpp
dom/filesystem/DeviceStorageFileSystem.h
dom/filesystem/Directory.cpp
dom/filesystem/Directory.h
dom/filesystem/FileSystemBase.cpp
dom/filesystem/FileSystemBase.h
dom/filesystem/GetDirectoryListingTask.cpp
dom/filesystem/GetDirectoryListingTask.h
dom/filesystem/GetFileOrDirectoryTask.cpp
dom/filesystem/GetFileOrDirectoryTask.h
dom/filesystem/OSFileSystem.cpp
dom/filesystem/OSFileSystem.h
dom/filesystem/PFileSystemParams.ipdlh
dom/filesystem/tests/filesystem_commons.js
dom/html/HTMLInputElement.cpp
widget/nsBaseFilePicker.cpp
widget/nsFilePickerProxy.cpp
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -702,60 +702,48 @@ WriteBlob(JSStructuredCloneWriter* aWrit
     aHolder->BlobImpls().AppendElement(blobImpl);
     return true;
   }
 
   return false;
 }
 
 // A directory is serialized as:
-// - pair of ints: SCTAG_DOM_DIRECTORY, 0
-// - pair of ints: type (eDOMRootDirectory/eDOMNotRootDirectory) - path length
+// - pair of ints: SCTAG_DOM_DIRECTORY, path length
 // - path as string
 bool
 WriteDirectory(JSStructuredCloneWriter* aWriter,
                Directory* aDirectory)
 {
   MOZ_ASSERT(aWriter);
   MOZ_ASSERT(aDirectory);
 
   nsAutoString path;
   aDirectory->GetFullRealPath(path);
 
   size_t charSize = sizeof(nsString::char_type);
-  return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DIRECTORY, 0) &&
-         JS_WriteUint32Pair(aWriter, (uint32_t)aDirectory->Type(),
-                            path.Length()) &&
+  return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DIRECTORY, path.Length()) &&
          JS_WriteBytes(aWriter, path.get(), path.Length() * charSize);
 }
 
 JSObject*
 ReadDirectory(JSContext* aCx,
               JSStructuredCloneReader* aReader,
-              uint32_t aZero,
+              uint32_t aPathLength,
               StructuredCloneHolder* aHolder)
 {
   MOZ_ASSERT(aCx);
   MOZ_ASSERT(aReader);
   MOZ_ASSERT(aHolder);
-  MOZ_ASSERT(aZero == 0);
-
-  uint32_t directoryType, lengthOfString;
-  if (!JS_ReadUint32Pair(aReader, &directoryType, &lengthOfString)) {
-    return nullptr;
-  }
-
-  MOZ_ASSERT(directoryType == Directory::eDOMRootDirectory ||
-             directoryType == Directory::eNotDOMRootDirectory);
 
   nsAutoString path;
-  path.SetLength(lengthOfString);
+  path.SetLength(aPathLength);
   size_t charSize = sizeof(nsString::char_type);
   if (!JS_ReadBytes(aReader, (void*) path.BeginWriting(),
-                    lengthOfString * charSize)) {
+                    aPathLength * charSize)) {
     return nullptr;
   }
 
   nsCOMPtr<nsIFile> file;
   nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
                                       getter_AddRefs(file));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
@@ -764,18 +752,17 @@ ReadDirectory(JSContext* aCx,
   // RefPtr<Directory> needs to go out of scope before toObject() is
   // called because the static analysis thinks dereferencing XPCOM objects
   // can GC (because in some cases it can!), and a return statement with a
   // JSObject* type means that JSObject* is on the stack as a raw pointer
   // while destructors are running.
   JS::Rooted<JS::Value> val(aCx);
   {
     RefPtr<Directory> directory =
-      Directory::Create(aHolder->ParentDuringRead(), file,
-                        (Directory::DirectoryType) directoryType);
+      Directory::Create(aHolder->ParentDuringRead(), file);
 
     if (!ToJSValue(aCx, directory, &val)) {
       return nullptr;
     }
   }
 
   return &val.toObject();
 }
--- a/dom/filesystem/CreateDirectoryTask.cpp
+++ b/dom/filesystem/CreateDirectoryTask.cpp
@@ -114,19 +114,17 @@ CreateDirectoryTaskChild::HandlerCallbac
 
   if (HasError()) {
     mPromise->MaybeReject(mErrorValue);
     mPromise = nullptr;
     return;
   }
 
   RefPtr<Directory> dir = Directory::Create(mFileSystem->GetParentObject(),
-                                            mTargetPath,
-                                            Directory::eNotDOMRootDirectory,
-                                            mFileSystem);
+                                            mTargetPath, mFileSystem);
   MOZ_ASSERT(dir);
 
   mPromise->MaybeResolve(dir);
   mPromise = nullptr;
 }
 
 void
 CreateDirectoryTaskChild::GetPermissionAccessType(nsCString& aAccess) const
--- a/dom/filesystem/DeviceStorageFileSystem.cpp
+++ b/dom/filesystem/DeviceStorageFileSystem.cpp
@@ -110,20 +110,42 @@ DeviceStorageFileSystem::GetParentObject
   AssertIsOnOwningThread();
 
   nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
   MOZ_ASSERT_IF(!mShutdown, window);
   return window ? window->AsInner() : nullptr;
 }
 
 void
-DeviceStorageFileSystem::GetRootName(nsAString& aRetval) const
+DeviceStorageFileSystem::GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
+                                          ErrorResult& aRv) const
 {
   AssertIsOnOwningThread();
-  aRetval = mStorageName;
+  MOZ_ASSERT(aFile);
+
+  nsCOMPtr<nsIFile> rootPath;
+  aRv = NS_NewLocalFile(LocalOrDeviceStorageRootPath(), false,
+                        getter_AddRefs(rootPath));
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  bool equal = false;
+  aRv = aFile->Equals(rootPath, &equal);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
+  }
+
+  if (equal) {
+    aRetval = mStorageName;
+    return;
+  }
+
+  FileSystemBase::GetDirectoryName(aFile, aRetval, aRv);
+  NS_WARN_IF(aRv.Failed());
 }
 
 bool
 DeviceStorageFileSystem::IsSafeFile(nsIFile* aFile) const
 {
   MOZ_ASSERT(XRE_IsParentProcess(), "Should be on parent process!");
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aFile);
--- a/dom/filesystem/DeviceStorageFileSystem.h
+++ b/dom/filesystem/DeviceStorageFileSystem.h
@@ -32,17 +32,18 @@ public:
 
   virtual void
   Shutdown() override;
 
   virtual nsISupports*
   GetParentObject() const override;
 
   virtual void
-  GetRootName(nsAString& aRetval) const override;
+  GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
+                   ErrorResult& aRv) const override;
 
   virtual bool
   IsSafeFile(nsIFile* aFile) const override;
 
   virtual bool
   IsSafeDirectory(Directory* aDir) const override;
 
   virtual void
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -132,58 +132,47 @@ Directory::GetRoot(FileSystemBase* aFile
   nsCOMPtr<nsIFile> path;
   aRv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(aFileSystem->LocalOrDeviceStorageRootPath()),
                               true, getter_AddRefs(path));
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   RefPtr<GetFileOrDirectoryTaskChild> task =
-    GetFileOrDirectoryTaskChild::Create(aFileSystem, path, eDOMRootDirectory,
-                                        true, aRv);
+    GetFileOrDirectoryTaskChild::Create(aFileSystem, path, true, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   FileSystemPermissionRequest::RequestForTask(task);
   return task->GetPromise();
 }
 
 /* static */ already_AddRefed<Directory>
 Directory::Create(nsISupports* aParent, nsIFile* aFile,
-                  DirectoryType aType, FileSystemBase* aFileSystem)
+                  FileSystemBase* aFileSystem)
 {
   MOZ_ASSERT(aParent);
   MOZ_ASSERT(aFile);
 
 #ifdef DEBUG
   bool isDir;
   nsresult rv = aFile->IsDirectory(&isDir);
   MOZ_ASSERT(NS_SUCCEEDED(rv) && isDir);
-
-  if (aType == eNotDOMRootDirectory) {
-    RefPtr<nsIFile> parent;
-    rv = aFile->GetParent(getter_AddRefs(parent));
-    // We must have a parent if this is not the root directory.
-    MOZ_ASSERT(NS_SUCCEEDED(rv) && parent);
-  }
 #endif
 
-  RefPtr<Directory> directory =
-    new Directory(aParent, aFile, aType, aFileSystem);
+  RefPtr<Directory> directory = new Directory(aParent, aFile, aFileSystem);
   return directory.forget();
 }
 
 Directory::Directory(nsISupports* aParent,
                      nsIFile* aFile,
-                     DirectoryType aType,
                      FileSystemBase* aFileSystem)
   : mParent(aParent)
   , mFile(aFile)
-  , mType(aType)
 {
   MOZ_ASSERT(aFile);
 
   // aFileSystem can be null. In this case we create a OSFileSystem when needed.
   if (aFileSystem) {
     // More likely, this is a OSFileSystem. This object keeps a reference of
     // mParent but it's not cycle collectable and to avoid manual
     // addref/release, it's better to have 1 object per directory. For this
@@ -208,28 +197,22 @@ Directory::WrapObject(JSContext* aCx, JS
   return DirectoryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 Directory::GetName(nsAString& aRetval, ErrorResult& aRv)
 {
   aRetval.Truncate();
 
-  if (mType == eDOMRootDirectory) {
-    RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
-
-    fs->GetRootName(aRetval);
+  RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
-  aRv = mFile->GetLeafName(aRetval);
-  NS_WARN_IF(aRv.Failed());
+  fs->GetDirectoryName(mFile, aRetval, aRv);
 }
 
 already_AddRefed<Promise>
 Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
                       ErrorResult& aRv)
 {
   // Only exposed for DeviceStorage.
   MOZ_ASSERT(NS_IsMainThread());
@@ -313,18 +296,17 @@ Directory::Get(const nsAString& aPath, E
   nsresult error = DOMPathToRealPath(aPath, getter_AddRefs(realPath));
 
   RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   RefPtr<GetFileOrDirectoryTaskChild> task =
-    GetFileOrDirectoryTaskChild::Create(fs, realPath, eNotDOMRootDirectory,
-                                        false, aRv);
+    GetFileOrDirectoryTaskChild::Create(fs, realPath, false, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   task->SetError(error);
   FileSystemPermissionRequest::RequestForTask(task);
   return task->GetPromise();
 }
@@ -404,17 +386,17 @@ Directory::GetPath(nsAString& aRetval, E
 {
   // This operation is expensive. Better to cache the result.
   if (mPath.IsEmpty()) {
     RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
 
-    fs->GetDOMPath(mFile, mType, mPath, aRv);
+    fs->GetDOMPath(mFile, mPath, aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
   }
 
   aRetval = mPath;
 }
 
@@ -433,17 +415,17 @@ already_AddRefed<Promise>
 Directory::GetFilesAndDirectories(ErrorResult& aRv)
 {
   RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   RefPtr<GetDirectoryListingTaskChild> task =
-    GetDirectoryListingTaskChild::Create(fs, mFile, mType, mFilters, aRv);
+    GetDirectoryListingTaskChild::Create(fs, mFile, mFilters, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   FileSystemPermissionRequest::RequestForTask(task);
   return task->GetPromise();
 }
 
@@ -473,20 +455,16 @@ Directory::SetContentFilters(const nsASt
 {
   mFilters = aFilters;
 }
 
 FileSystemBase*
 Directory::GetFileSystem(ErrorResult& aRv)
 {
   if (!mFileSystem) {
-    // Any subdir inherits the FileSystem of the parent Directory. If we are
-    // here it's because we are dealing with the DOM root.
-    MOZ_ASSERT(mType == eDOMRootDirectory);
-
     nsAutoString path;
     aRv = mFile->GetPath(path);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
     RefPtr<OSFileSystem> fs = new OSFileSystem(path);
     fs->Init(mParent);
--- a/dom/filesystem/Directory.h
+++ b/dom/filesystem/Directory.h
@@ -54,30 +54,19 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Directory)
 
   static bool
   DeviceStorageEnabled(JSContext* aCx, JSObject* aObj);
 
   static already_AddRefed<Promise>
   GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv);
 
-  enum DirectoryType {
-    // When a directory is selected using a HTMLInputElement, that will be the
-    // DOM root directory and its name will be '/'. All the sub directory will
-    // be called with they real name. We use this enum to mark what we must
-    // consider the '/' of this DOM filesystem.
-    eDOMRootDirectory,
-
-    // All the sub directories of the '/' will be marked using this other value.
-    eNotDOMRootDirectory
-  };
-
   static already_AddRefed<Directory>
   Create(nsISupports* aParent, nsIFile* aDirectory,
-         DirectoryType aType, FileSystemBase* aFileSystem = 0);
+         FileSystemBase* aFileSystem = 0);
 
   // ========= Begin WebIDL bindings. ===========
 
   nsISupports*
   GetParentObject() const;
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -140,44 +129,38 @@ public:
    * picker operation.
    */
   void
   SetContentFilters(const nsAString& aFilters);
 
   FileSystemBase*
   GetFileSystem(ErrorResult& aRv);
 
-  DirectoryType Type() const
-  {
-    return mType;
-  }
-
   bool
   ClonableToDifferentThreadOrProcess() const;
 
 private:
   Directory(nsISupports* aParent,
-            nsIFile* aFile, DirectoryType aType,
+            nsIFile* aFile,
             FileSystemBase* aFileSystem = nullptr);
   ~Directory();
 
   /*
    * Convert relative DOM path to the absolute real path.
    */
   nsresult
   DOMPathToRealPath(const nsAString& aPath, nsIFile** aFile) const;
 
   already_AddRefed<Promise>
   RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive,
                  ErrorResult& aRv);
 
   nsCOMPtr<nsISupports> mParent;
   RefPtr<FileSystemBase> mFileSystem;
   nsCOMPtr<nsIFile> mFile;
-  DirectoryType mType;
 
   nsString mFilters;
   nsString mPath;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/filesystem/FileSystemBase.cpp
+++ b/dom/filesystem/FileSystemBase.cpp
@@ -106,83 +106,86 @@ FileSystemBase::IsSafeFile(nsIFile* aFil
 bool
 FileSystemBase::IsSafeDirectory(Directory* aDir) const
 {
   AssertIsOnOwningThread();
   return false;
 }
 
 void
+FileSystemBase::GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
+                                 ErrorResult& aRv) const
+{
+  AssertIsOnOwningThread();
+  MOZ_ASSERT(aFile);
+
+  aRv = aFile->GetLeafName(aRetval);
+  NS_WARN_IF(aRv.Failed());
+}
+
+void
 FileSystemBase::GetDOMPath(nsIFile* aFile,
-                           Directory::DirectoryType aType,
                            nsAString& aRetval,
                            ErrorResult& aRv) const
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aFile);
 
-  if (aType == Directory::eDOMRootDirectory) {
-    aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
-    return;
-  }
+  aRetval.Truncate();
 
   nsCOMPtr<nsIFile> fileSystemPath;
   aRv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(LocalOrDeviceStorageRootPath()),
                               true, getter_AddRefs(fileSystemPath));
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
-  MOZ_ASSERT(FileSystemUtils::IsDescendantPath(fileSystemPath, aFile));
-
   nsCOMPtr<nsIFile> path;
   aRv = aFile->Clone(getter_AddRefs(path));
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   nsTArray<nsString> parts;
 
   while (true) {
+    nsAutoString leafName;
+    aRv = path->GetLeafName(leafName);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return;
+    }
+
+    parts.AppendElement(leafName);
+
     bool equal = false;
     aRv = fileSystemPath->Equals(path, &equal);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
 
     if (equal) {
       break;
     }
 
-    nsAutoString leafName;
-    aRv = path->GetLeafName(leafName);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
-
-    parts.AppendElement(leafName);
-
     nsCOMPtr<nsIFile> parentPath;
     aRv = path->GetParent(getter_AddRefs(parentPath));
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
 
     MOZ_ASSERT(parentPath);
 
     aRv = parentPath->Clone(getter_AddRefs(path));
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
   }
 
   MOZ_ASSERT(!parts.IsEmpty());
 
-  aRetval.Truncate();
-
   for (int32_t i = parts.Length() - 1; i >= 0; --i) {
     aRetval.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
     aRetval.Append(parts[i]);
   }
 }
 
 void
 FileSystemBase::AssertIsOnOwningThread() const
--- a/dom/filesystem/FileSystemBase.h
+++ b/dom/filesystem/FileSystemBase.h
@@ -35,26 +35,22 @@ public:
   SerializeDOMPath(nsAString& aOutput) const = 0;
 
   virtual already_AddRefed<FileSystemBase>
   Clone() = 0;
 
   virtual nsISupports*
   GetParentObject() const;
 
-  /*
-   * Get the virtual name of the root directory. This name will be exposed to
-   * the content page.
-   */
   virtual void
-  GetRootName(nsAString& aRetval) const = 0;
+  GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
+                   ErrorResult& aRv) const;
 
   void
-  GetDOMPath(nsIFile* aFile, Directory::DirectoryType aType,
-             nsAString& aRetval, ErrorResult& aRv) const;
+  GetDOMPath(nsIFile* aFile, nsAString& aRetval, ErrorResult& aRv) const;
 
   /*
    * Return the local root path of the FileSystem implementation.
    * For OSFileSystem, this is equal to the path of the root Directory;
    * For DeviceStorageFileSystem, this is the path of the SDCard, parent
    * directory of the exposed root Directory (per type).
    */
   const nsAString&
--- a/dom/filesystem/GetDirectoryListingTask.cpp
+++ b/dom/filesystem/GetDirectoryListingTask.cpp
@@ -23,25 +23,24 @@ namespace dom {
 
 /**
  * GetDirectoryListingTaskChild
  */
 
 /* static */ already_AddRefed<GetDirectoryListingTaskChild>
 GetDirectoryListingTaskChild::Create(FileSystemBase* aFileSystem,
                                      nsIFile* aTargetPath,
-                                     Directory::DirectoryType aType,
                                      const nsAString& aFilters,
                                      ErrorResult& aRv)
 {
   MOZ_ASSERT(aFileSystem);
   aFileSystem->AssertIsOnOwningThread();
 
   RefPtr<GetDirectoryListingTaskChild> task =
-    new GetDirectoryListingTaskChild(aFileSystem, aTargetPath, aType, aFilters);
+    new GetDirectoryListingTaskChild(aFileSystem, aTargetPath, aFilters);
 
   // aTargetPath can be null. In this case SetError will be called.
 
   nsCOMPtr<nsIGlobalObject> globalObject =
     do_QueryInterface(aFileSystem->GetParentObject());
   if (NS_WARN_IF(!globalObject)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -52,22 +51,20 @@ GetDirectoryListingTaskChild::Create(Fil
     return nullptr;
   }
 
   return task.forget();
 }
 
 GetDirectoryListingTaskChild::GetDirectoryListingTaskChild(FileSystemBase* aFileSystem,
                                                            nsIFile* aTargetPath,
-                                                           Directory::DirectoryType aType,
                                                            const nsAString& aFilters)
   : FileSystemTaskChildBase(aFileSystem)
   , mTargetPath(aTargetPath)
   , mFilters(aFilters)
-  , mType(aType)
 {
   MOZ_ASSERT(aFileSystem);
   aFileSystem->AssertIsOnOwningThread();
 }
 
 GetDirectoryListingTaskChild::~GetDirectoryListingTaskChild()
 {
   mFileSystem->AssertIsOnOwningThread();
@@ -88,17 +85,16 @@ GetDirectoryListingTaskChild::GetRequest
 
   nsAutoString path;
   aRv = mTargetPath->GetPath(path);
   if (NS_WARN_IF(aRv.Failed())) {
     return FileSystemGetDirectoryListingParams();
   }
 
   return FileSystemGetDirectoryListingParams(aSerializedDOMPath, path,
-                                             mType == Directory::eDOMRootDirectory,
                                              mFilters);
 }
 
 void
 GetDirectoryListingTaskChild::SetSuccessRequestResult(const FileSystemResponseValue& aValue,
                                                       ErrorResult& aRv)
 {
   mFileSystem->AssertIsOnOwningThread();
@@ -174,18 +170,17 @@ GetDirectoryListingTaskChild::HandlerCal
       return;
     }
 
     MOZ_ASSERT(FileSystemUtils::IsDescendantPath(rootPath, path));
 #endif
 
     if (mTargetData[i].mType == Directory::FileOrDirectoryPath::eDirectoryPath) {
       RefPtr<Directory> directory =
-        Directory::Create(mFileSystem->GetParentObject(), path,
-                          Directory::eNotDOMRootDirectory, mFileSystem);
+        Directory::Create(mFileSystem->GetParentObject(), path, mFileSystem);
       MOZ_ASSERT(directory);
 
       // Propogate mFilter onto sub-Directory object:
       directory->SetContentFilters(mFilters);
       listing[i].SetAsDirectory() = directory;
     } else {
       MOZ_ASSERT(mTargetData[i].mType == Directory::FileOrDirectoryPath::eFilePath);
 
@@ -225,18 +220,16 @@ GetDirectoryListingTaskParent::Create(Fi
     new GetDirectoryListingTaskParent(aFileSystem, aParam, aParent);
 
   NS_ConvertUTF16toUTF8 path(aParam.realPath());
   aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(task->mTargetPath));
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  task->mType = aParam.isRoot()
-                  ? Directory::eDOMRootDirectory : Directory::eNotDOMRootDirectory;
   return task.forget();
 }
 
 GetDirectoryListingTaskParent::GetDirectoryListingTaskParent(FileSystemBase* aFileSystem,
                                                              const FileSystemGetDirectoryListingParams& aParam,
                                                              FileSystemRequestParent* aParent)
   : FileSystemTaskParentBase(aFileSystem, aParam, aParent)
   , mFilters(aParam.filters())
@@ -286,25 +279,17 @@ GetDirectoryListingTaskParent::IOWork()
 
   bool exists;
   nsresult rv = mTargetPath->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (!exists) {
-    if (mType == Directory::eNotDOMRootDirectory) {
-      return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
-    }
-
-    // If the root directory doesn't exit, create it.
-    rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
   }
 
   // Get isDirectory.
   bool isDir;
   rv = mTargetPath->IsDirectory(&isDir);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
--- a/dom/filesystem/GetDirectoryListingTask.h
+++ b/dom/filesystem/GetDirectoryListingTask.h
@@ -18,51 +18,48 @@ namespace dom {
 class BlobImpl;
 
 class GetDirectoryListingTaskChild final : public FileSystemTaskChildBase
 {
 public:
   static already_AddRefed<GetDirectoryListingTaskChild>
   Create(FileSystemBase* aFileSystem,
          nsIFile* aTargetPath,
-         Directory::DirectoryType aType,
          const nsAString& aFilters,
          ErrorResult& aRv);
 
   virtual
   ~GetDirectoryListingTaskChild();
 
   already_AddRefed<Promise>
   GetPromise();
 
   virtual void
   GetPermissionAccessType(nsCString& aAccess) const override;
 
 private:
   // If aDirectoryOnly is set, we should ensure that the target is a directory.
   GetDirectoryListingTaskChild(FileSystemBase* aFileSystem,
                                nsIFile* aTargetPath,
-                               Directory::DirectoryType aType,
                                const nsAString& aFilters);
 
   virtual FileSystemParams
   GetRequestParams(const nsString& aSerializedDOMPath,
                    ErrorResult& aRv) const override;
 
   virtual void
   SetSuccessRequestResult(const FileSystemResponseValue& aValue,
                           ErrorResult& aRv) override;
 
   virtual void
   HandlerCallback() override;
 
   RefPtr<Promise> mPromise;
   nsCOMPtr<nsIFile> mTargetPath;
   nsString mFilters;
-  Directory::DirectoryType mType;
 
   // We cannot store File or Directory objects bacause this object is created
   // on a different thread and File and Directory are not thread-safe.
   FallibleTArray<Directory::FileOrDirectoryPath> mTargetData;
 };
 
 class GetDirectoryListingTaskParent final : public FileSystemTaskParentBase
 {
@@ -84,17 +81,16 @@ private:
   virtual FileSystemResponseValue
   GetSuccessRequestResult(ErrorResult& aRv) const override;
 
   virtual nsresult
   IOWork() override;
 
   nsCOMPtr<nsIFile> mTargetPath;
   nsString mFilters;
-  Directory::DirectoryType mType;
 
   // We cannot store File or Directory objects bacause this object is created
   // on a different thread and File and Directory are not thread-safe.
   FallibleTArray<Directory::FileOrDirectoryPath> mTargetData;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/filesystem/GetFileOrDirectoryTask.cpp
+++ b/dom/filesystem/GetFileOrDirectoryTask.cpp
@@ -22,26 +22,24 @@ namespace dom {
 
 /**
  * GetFileOrDirectoryTaskChild
  */
 
 /* static */ already_AddRefed<GetFileOrDirectoryTaskChild>
 GetFileOrDirectoryTaskChild::Create(FileSystemBase* aFileSystem,
                                     nsIFile* aTargetPath,
-                                    Directory::DirectoryType aType,
                                     bool aDirectoryOnly,
                                     ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
 
   RefPtr<GetFileOrDirectoryTaskChild> task =
-    new GetFileOrDirectoryTaskChild(aFileSystem, aTargetPath, aType,
-                                    aDirectoryOnly);
+    new GetFileOrDirectoryTaskChild(aFileSystem, aTargetPath, aDirectoryOnly);
 
   // aTargetPath can be null. In this case SetError will be called.
 
   nsCOMPtr<nsIGlobalObject> globalObject =
     do_QueryInterface(aFileSystem->GetParentObject());
   if (NS_WARN_IF(!globalObject)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -52,22 +50,20 @@ GetFileOrDirectoryTaskChild::Create(File
     return nullptr;
   }
 
   return task.forget();
 }
 
 GetFileOrDirectoryTaskChild::GetFileOrDirectoryTaskChild(FileSystemBase* aFileSystem,
                                                          nsIFile* aTargetPath,
-                                                         Directory::DirectoryType aType,
                                                          bool aDirectoryOnly)
   : FileSystemTaskChildBase(aFileSystem)
   , mTargetPath(aTargetPath)
   , mIsDirectory(aDirectoryOnly)
-  , mType(aType)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
 }
 
 GetFileOrDirectoryTaskChild::~GetFileOrDirectoryTaskChild()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -87,18 +83,17 @@ GetFileOrDirectoryTaskChild::GetRequestP
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
 
   nsAutoString path;
   aRv = mTargetPath->GetPath(path);
   if (NS_WARN_IF(aRv.Failed())) {
     return FileSystemGetFileOrDirectoryParams();
   }
 
-  return FileSystemGetFileOrDirectoryParams(aSerializedDOMPath, path,
-                                            mType == Directory::eDOMRootDirectory);
+  return FileSystemGetFileOrDirectoryParams(aSerializedDOMPath, path);
 }
 
 void
 GetFileOrDirectoryTaskChild::SetSuccessRequestResult(const FileSystemResponseValue& aValue,
                                                      ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   switch (aValue.type()) {
@@ -146,17 +141,16 @@ GetFileOrDirectoryTaskChild::HandlerCall
     mPromise->MaybeReject(mErrorValue);
     mPromise = nullptr;
     return;
   }
 
   if (mIsDirectory) {
     RefPtr<Directory> dir = Directory::Create(mFileSystem->GetParentObject(),
                                               mTargetPath,
-                                              mType,
                                               mFileSystem);
     MOZ_ASSERT(dir);
 
     mPromise->MaybeResolve(dir);
     mPromise = nullptr;
     return;
   }
 
@@ -190,18 +184,16 @@ GetFileOrDirectoryTaskParent::Create(Fil
     new GetFileOrDirectoryTaskParent(aFileSystem, aParam, aParent);
 
   NS_ConvertUTF16toUTF8 path(aParam.realPath());
   aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(task->mTargetPath));
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  task->mType = aParam.isRoot()
-                  ? Directory::eDOMRootDirectory : Directory::eNotDOMRootDirectory;
   return task.forget();
 }
 
 GetFileOrDirectoryTaskParent::GetFileOrDirectoryTaskParent(FileSystemBase* aFileSystem,
                                                            const FileSystemGetFileOrDirectoryParams& aParam,
                                                            FileSystemRequestParent* aParent)
   : FileSystemTaskParentBase(aFileSystem, aParam, aParent)
   , mIsDirectory(false)
@@ -243,42 +235,29 @@ GetFileOrDirectoryTaskParent::IOWork()
   // Whether we want to get the root directory.
   bool exists;
   nsresult rv = mTargetPath->Exists(&exists);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (!exists) {
-    if (mType == Directory::eNotDOMRootDirectory) {
-      return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
-    }
-
-    // If the root directory doesn't exit, create it.
-    rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
   }
 
   // Get isDirectory.
   rv = mTargetPath->IsDirectory(&mIsDirectory);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (mIsDirectory) {
     return NS_OK;
   }
 
-  // Check if the root is a directory.
-  if (mType == Directory::eDOMRootDirectory) {
-    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
-  }
-
   bool isFile;
   // Get isFile
   rv = mTargetPath->IsFile(&isFile);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (!isFile) {
--- a/dom/filesystem/GetFileOrDirectoryTask.h
+++ b/dom/filesystem/GetFileOrDirectoryTask.h
@@ -18,17 +18,16 @@ namespace dom {
 class BlobImpl;
 
 class GetFileOrDirectoryTaskChild final : public FileSystemTaskChildBase
 {
 public:
   static already_AddRefed<GetFileOrDirectoryTaskChild>
   Create(FileSystemBase* aFileSystem,
          nsIFile* aTargetPath,
-         Directory::DirectoryType aType,
          bool aDirectoryOnly,
          ErrorResult& aRv);
 
   virtual
   ~GetFileOrDirectoryTaskChild();
 
   already_AddRefed<Promise>
   GetPromise();
@@ -46,25 +45,23 @@ protected:
                           ErrorResult& aRv) override;
   virtual void
   HandlerCallback() override;
 
 private:
   // If aDirectoryOnly is set, we should ensure that the target is a directory.
   GetFileOrDirectoryTaskChild(FileSystemBase* aFileSystem,
                               nsIFile* aTargetPath,
-                              Directory::DirectoryType aType,
                               bool aDirectoryOnly);
 
   RefPtr<Promise> mPromise;
   nsCOMPtr<nsIFile> mTargetPath;
 
   // Whether we get a directory.
   bool mIsDirectory;
-  Directory::DirectoryType mType;
 };
 
 class GetFileOrDirectoryTaskParent final : public FileSystemTaskParentBase
 {
 public:
   static already_AddRefed<GetFileOrDirectoryTaskParent>
   Create(FileSystemBase* aFileSystem,
          const FileSystemGetFileOrDirectoryParams& aParam,
@@ -85,15 +82,14 @@ private:
   GetFileOrDirectoryTaskParent(FileSystemBase* aFileSystem,
                                const FileSystemGetFileOrDirectoryParams& aParam,
                                FileSystemRequestParent* aParent);
 
   nsCOMPtr<nsIFile> mTargetPath;
 
   // Whether we get a directory.
   bool mIsDirectory;
-  Directory::DirectoryType mType;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_GetFileOrDirectory_h
--- a/dom/filesystem/OSFileSystem.cpp
+++ b/dom/filesystem/OSFileSystem.cpp
@@ -57,23 +57,16 @@ OSFileSystem::Init(nsISupports* aParent)
 
 nsISupports*
 OSFileSystem::GetParentObject() const
 {
   AssertIsOnOwningThread();
   return mParent;
 }
 
-void
-OSFileSystem::GetRootName(nsAString& aRetval) const
-{
-  AssertIsOnOwningThread();
-  aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
-}
-
 bool
 OSFileSystem::IsSafeFile(nsIFile* aFile) const
 {
   // The concept of "safe files" is specific to the Device Storage API where
   // files are only "safe" if they're of a type that is appropriate for the
   // area of device storage that is being used.
   MOZ_CRASH("Don't use OSFileSystem with the Device Storage API");
   return true;
--- a/dom/filesystem/OSFileSystem.h
+++ b/dom/filesystem/OSFileSystem.h
@@ -23,19 +23,16 @@ public:
   // Overrides FileSystemBase
 
   virtual already_AddRefed<FileSystemBase>
   Clone() override;
 
   virtual nsISupports*
   GetParentObject() const override;
 
-  virtual void
-  GetRootName(nsAString& aRetval) const override;
-
   virtual bool
   IsSafeFile(nsIFile* aFile) const override;
 
   virtual bool
   IsSafeDirectory(Directory* aDir) const override;
 
   virtual void
   SerializeDOMPath(nsAString& aOutput) const override;
@@ -70,17 +67,18 @@ public:
   virtual nsISupports*
   GetParentObject() const override
   {
     MOZ_CRASH("This should not be called on the PBackground thread.");
     return nullptr;
   }
 
   virtual void
-  GetRootName(nsAString& aRetval) const override
+  GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
+                   ErrorResult& aRv) const override
   {
     MOZ_CRASH("This should not be called on the PBackground thread.");
   }
 
   virtual bool
   IsSafeFile(nsIFile* aFile) const override
   {
     MOZ_CRASH("This should not be called on the PBackground thread.");
--- a/dom/filesystem/PFileSystemParams.ipdlh
+++ b/dom/filesystem/PFileSystemParams.ipdlh
@@ -26,17 +26,17 @@ struct FileSystemCreateFileParams
   FileSystemFileDataValue data;
   bool replace;
 };
 
 struct FileSystemGetDirectoryListingParams
 {
   nsString filesystem;
   nsString realPath;
-  bool isRoot;
+
   // 'filters' could be an array rather than a semicolon separated string
   // (we'd then use InfallibleTArray<nsString> internally), but that is
   // wasteful.  E10s requires us to pass the filters over as a string anyway,
   // so avoiding using an array avoids serialization on the side passing the
   // filters.  Since an nsString can share its buffer when copied,
   // using that instead of InfallibleTArray<nsString> makes copying the filters
   // around in any given process a bit more efficient too, since copying a
   // single nsString is cheaper than copying InfallibleTArray member data and
@@ -50,17 +50,16 @@ struct FileSystemGetFilesParams
   nsString realPath;
   bool recursiveFlag;
 };
 
 struct FileSystemGetFileOrDirectoryParams
 {
   nsString filesystem;
   nsString realPath;
-  bool isRoot;
 };
 
 struct FileSystemRemoveParams
 {
   nsString filesystem;
   nsString directory;
   nsString targetDirectory;
   bool recursive;
--- a/dom/filesystem/tests/filesystem_commons.js
+++ b/dom/filesystem/tests/filesystem_commons.js
@@ -1,42 +1,41 @@
 function test_basic(aDirectory, aNext) {
   ok(aDirectory, "Directory exists.");
   ok(aDirectory instanceof Directory, "We have a directory.");
-  is(aDirectory.name, '/', "directory.name must be '/'");
-  is(aDirectory.path, '/', "directory.path must be '/'");
+  is(aDirectory.path, '/' + aDirectory.name, "directory.path must be '/'+name");
   aNext();
 }
 
 function test_getFilesAndDirectories(aDirectory, aRecursive, aNext) {
   function checkSubDir(dir) {
     return dir.getFilesAndDirectories().then(
       function(data) {
         for (var i = 0; i < data.length; ++i) {
           ok (data[i] instanceof File || data[i] instanceof Directory, "Just Files or Directories");
           if (data[i] instanceof Directory) {
             isnot(data[i].name, '/', "Subdirectory should be called with the leafname");
             isnot(data[i].path, '/', "Subdirectory path should be called with the leafname");
             isnot(data[i].path, dir.path, "Subdirectory path should contain the parent path.");
-            is(data[i].path,dir.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
+            is(data[i].path, dir.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
           }
         }
       }
     );
   }
 
   aDirectory.getFilesAndDirectories().then(
     function(data) {
       ok(data.length, "We should have some data.");
       var promises = [];
       for (var i = 0; i < data.length; ++i) {
         ok (data[i] instanceof File || data[i] instanceof Directory, "Just Files or Directories: " + data[i].name);
         if (data[i] instanceof Directory) {
           isnot(data[i].name, '/', "Subdirectory should be called with the leafname");
-          is(data[i].path, '/' + data[i].name, "Subdirectory path should be called '/' + leafname");
+          is(data[i].path, aDirectory.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
           if (aRecursive) {
             promises.push(checkSubDir(data[i]));
           }
         }
       }
 
       return Promise.all(promises);
     },
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -267,18 +267,17 @@ class HTMLInputElementState final : publ
 
           nsCOMPtr<nsIFile> file;
           NS_ConvertUTF16toUTF8 path(mBlobImplsOrDirectoryPaths[i].mDirectoryPath);
           nsresult rv = NS_NewNativeLocalFile(path, true, getter_AddRefs(file));
           if (NS_WARN_IF(NS_FAILED(rv))) {
             continue;
           }
 
-          RefPtr<Directory> directory = Directory::Create(aWindow, file,
-                                                          Directory::eDOMRootDirectory);
+          RefPtr<Directory> directory = Directory::Create(aWindow, file);
           MOZ_ASSERT(directory);
 
           OwningFileOrDirectory* element = aResult.AppendElement();
           element->SetAsDirectory() = directory;
         }
       }
     }
 
@@ -2306,18 +2305,17 @@ HTMLInputElement::MozSetDirectory(const 
   }
 
   nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow();
   if (NS_WARN_IF(!window)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
-  RefPtr<Directory> directory = Directory::Create(window, file,
-                                                  Directory::eDOMRootDirectory);
+  RefPtr<Directory> directory = Directory::Create(window, file);
   MOZ_ASSERT(directory);
 
   nsTArray<OwningFileOrDirectory> array;
   OwningFileOrDirectory* element = array.AppendElement();
   element->SetAsDirectory() = directory;
 
   SetFilesOrDirectories(array, true);
 }
--- a/widget/nsBaseFilePicker.cpp
+++ b/widget/nsBaseFilePicker.cpp
@@ -41,18 +41,17 @@ LocalFileToDirectoryOrBlob(nsPIDOMWindow
 {
   if (aIsDirectory) {
 #ifdef DEBUG
     bool isDir;
     aFile->IsDirectory(&isDir);
     MOZ_ASSERT(isDir);
 #endif
 
-    RefPtr<Directory> directory =
-      Directory::Create(aWindow, aFile, Directory::eDOMRootDirectory);
+    RefPtr<Directory> directory = Directory::Create(aWindow, aFile);
     MOZ_ASSERT(directory);
 
     directory.forget(aResult);
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMBlob> blob = File::CreateFromFile(aWindow, aFile);
   blob.forget(aResult);
--- a/widget/nsFilePickerProxy.cpp
+++ b/widget/nsFilePickerProxy.cpp
@@ -169,18 +169,17 @@ nsFilePickerProxy::Recv__delete__(const 
     nsCOMPtr<nsIFile> file;
     NS_ConvertUTF16toUTF8 path(aData.get_InputDirectory().directoryPath());
     nsresult rv = NS_NewNativeLocalFile(path, true, getter_AddRefs(file));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return true;
     }
 
     RefPtr<Directory> directory =
-      Directory::Create(mParent->GetCurrentInnerWindow(), file,
-                        Directory::eDOMRootDirectory);
+      Directory::Create(mParent->GetCurrentInnerWindow(), file);
     MOZ_ASSERT(directory);
 
     OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement();
     element->SetAsDirectory() = directory;
   }
 
   if (mCallback) {
     mCallback->Done(aResult);