Bug 1164310, part 2 - Implement an abstraction for a rooted filesystem for non-mobile devices. r=baku

This commit is contained in:
Jonathan Watt 2015-07-10 18:54:53 +01:00
parent 8e2b473096
commit b905e3a1be
8 changed files with 205 additions and 77 deletions

View File

@ -97,45 +97,10 @@ DeviceStorageFileSystem::GetWindow() const
return mDeviceStorage->GetOwner();
}
already_AddRefed<nsIFile>
DeviceStorageFileSystem::GetLocalFile(const nsAString& aRealPath) const
void
DeviceStorageFileSystem::GetRootName(nsAString& aRetval) const
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Should be on parent process!");
nsAutoString localPath;
FileSystemUtils::NormalizedPathToLocalPath(aRealPath, localPath);
localPath = mLocalRootPath + localPath;
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(localPath, false, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return file.forget();
}
bool
DeviceStorageFileSystem::GetRealPath(BlobImpl* aFile, nsAString& aRealPath) const
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Should be on parent process!");
MOZ_ASSERT(aFile, "aFile Should not be null.");
aRealPath.Truncate();
nsAutoString filePath;
ErrorResult rv;
aFile->GetMozFullPathInternal(filePath, rv);
if (NS_WARN_IF(rv.Failed())) {
return false;
}
return LocalPathToRealPath(filePath, aRealPath);
}
const nsAString&
DeviceStorageFileSystem::GetRootName() const
{
return mStorageName;
aRetval = mStorageName;
}
bool
@ -172,19 +137,5 @@ DeviceStorageFileSystem::IsSafeDirectory(Directory* aDir) const
return fs->ToString() == mString;
}
bool
DeviceStorageFileSystem::LocalPathToRealPath(const nsAString& aLocalPath,
nsAString& aRealPath) const
{
nsAutoString path;
FileSystemUtils::LocalPathToNormalizedPath(aLocalPath, path);
if (!FileSystemUtils::IsDescendantPath(mNormalizedLocalRootPath, path)) {
aRealPath.Truncate();
return false;
}
aRealPath = Substring(path, mNormalizedLocalRootPath.Length());
return true;
}
} // namespace dom
} // namespace mozilla

View File

@ -33,14 +33,8 @@ public:
virtual nsPIDOMWindow*
GetWindow() const override;
virtual already_AddRefed<nsIFile>
GetLocalFile(const nsAString& aRealPath) const override;
virtual bool
GetRealPath(BlobImpl* aFile, nsAString& aRealPath) const override;
virtual const nsAString&
GetRootName() const override;
virtual void
GetRootName(nsAString& aRetval) const override;
virtual bool
IsSafeFile(nsIFile* aFile) const override;
@ -51,16 +45,9 @@ private:
virtual
~DeviceStorageFileSystem();
bool
LocalPathToRealPath(const nsAString& aLocalPath, nsAString& aRealPath) const;
nsString mStorageType;
nsString mStorageName;
// The local path of the root. Only available in the parent process.
// In the child process, we don't use it and its value should be empty.
nsString mLocalRootPath;
nsString mNormalizedLocalRootPath;
nsDOMDeviceStorage* mDeviceStorage;
};

View File

@ -87,7 +87,7 @@ Directory::GetName(nsAString& aRetval) const
aRetval.Truncate();
if (mPath.IsEmpty()) {
aRetval = mFileSystem->GetRootName();
mFileSystem->GetRootName(aRetval);
return;
}

View File

@ -8,6 +8,7 @@
#include "DeviceStorageFileSystem.h"
#include "nsCharSeparatedTokenizer.h"
#include "OSFileSystem.h"
namespace mozilla {
namespace dom {
@ -37,7 +38,7 @@ FileSystemBase::FromString(const nsAString& aString)
new DeviceStorageFileSystem(storageType, storageName);
return f.forget();
}
return nullptr;
return nsRefPtr<OSFileSystem>(new OSFileSystem(aString)).forget();
}
FileSystemBase::FileSystemBase()
@ -62,6 +63,41 @@ FileSystemBase::GetWindow() const
return nullptr;
}
already_AddRefed<nsIFile>
FileSystemBase::GetLocalFile(const nsAString& aRealPath) const
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Should be on parent process!");
nsAutoString localPath;
FileSystemUtils::NormalizedPathToLocalPath(aRealPath, localPath);
localPath = mLocalRootPath + localPath;
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(localPath, false, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return file.forget();
}
bool
FileSystemBase::GetRealPath(BlobImpl* aFile, nsAString& aRealPath) const
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Should be on parent process!");
MOZ_ASSERT(aFile, "aFile Should not be null.");
aRealPath.Truncate();
nsAutoString filePath;
ErrorResult rv;
aFile->GetMozFullPathInternal(filePath, rv);
if (NS_WARN_IF(rv.Failed())) {
return false;
}
return LocalPathToRealPath(filePath, aRealPath);
}
bool
FileSystemBase::IsSafeFile(nsIFile* aFile) const
{
@ -74,5 +110,19 @@ FileSystemBase::IsSafeDirectory(Directory* aDir) const
return false;
}
bool
FileSystemBase::LocalPathToRealPath(const nsAString& aLocalPath,
nsAString& aRealPath) const
{
nsAutoString path;
FileSystemUtils::LocalPathToNormalizedPath(aLocalPath, path);
if (!FileSystemUtils::IsDescendantPath(mNormalizedLocalRootPath, path)) {
aRealPath.Truncate();
return false;
}
aRealPath = Substring(path, mNormalizedLocalRootPath.Length());
return true;
}
} // namespace dom
} // namespace mozilla

View File

@ -42,18 +42,18 @@ public:
virtual nsPIDOMWindow*
GetWindow() const;
/*
* Create nsIFile object with the given real path (absolute DOM path).
/**
* Create nsIFile object from the given real path (absolute DOM path).
*/
virtual already_AddRefed<nsIFile>
GetLocalFile(const nsAString& aRealPath) const = 0;
already_AddRefed<nsIFile>
GetLocalFile(const nsAString& aRealPath) const;
/*
* Get the virtual name of the root directory. This name will be exposed to
* the content page.
*/
virtual const nsAString&
GetRootName() const = 0;
virtual void
GetRootName(nsAString& aRetval) const = 0;
bool
IsShutdown() const
@ -72,8 +72,8 @@ public:
* If succeeded, returns true. Otherwise, returns false and set aRealPath to
* empty string.
*/
virtual bool
GetRealPath(BlobImpl* aFile, nsAString& aRealPath) const = 0;
bool
GetRealPath(BlobImpl* aFile, nsAString& aRealPath) const;
/*
* Get the permission name required to access this file system.
@ -92,6 +92,18 @@ public:
protected:
virtual ~FileSystemBase();
bool
LocalPathToRealPath(const nsAString& aLocalPath, nsAString& aRealPath) const;
// The local path of the root (i.e. the OS path, with OS path separators, of
// the OS directory that acts as the root of this OSFileSystem).
// Only available in the parent process.
// In the child process, we don't use it and its value should be empty.
nsString mLocalRootPath;
// The same, but with path separators normalized to "/".
nsString mNormalizedLocalRootPath;
// The string representation of the file system.
nsString mString;

View File

@ -0,0 +1,80 @@
/* -*- 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 "mozilla/dom/OSFileSystem.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"
#include "nsIFile.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
OSFileSystem::OSFileSystem(const nsAString& aRootDir)
{
mLocalRootPath = aRootDir;
FileSystemUtils::LocalPathToNormalizedPath(mLocalRootPath,
mNormalizedLocalRootPath);
// Non-mobile devices don't have the concept of separate permissions to
// access different parts of devices storage like Pictures, or Videos, etc.
mRequiresPermissionChecks = false;
mString = mLocalRootPath;
#ifdef DEBUG
mPermission.AssignLiteral("never-used");
#endif
}
void
OSFileSystem::Init(nsPIDOMWindow* aWindow)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
MOZ_ASSERT(!mWindow, "No duple Init() calls");
MOZ_ASSERT(aWindow);
mWindow = aWindow;
}
nsPIDOMWindow*
OSFileSystem::GetWindow() const
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
return mWindow;
}
void
OSFileSystem::GetRootName(nsAString& aRetval) const
{
return aRetval.AssignLiteral("/");
}
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;
}
bool
OSFileSystem::IsSafeDirectory(Directory* aDir) const
{
// The concept of "safe directory" is specific to the Device Storage API
// where a directory is only "safe" if it belongs to the area of device
// storage that it is being used with.
MOZ_CRASH("Don't use OSFileSystem with the Device Storage API");
return true;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,46 @@
/* -*- 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_OSFileSystem_h
#define mozilla_dom_OSFileSystem_h
#include "mozilla/dom/FileSystemBase.h"
namespace mozilla {
namespace dom {
class OSFileSystem : public FileSystemBase
{
public:
explicit OSFileSystem(const nsAString& aRootDir);
void
Init(nsPIDOMWindow* aWindow);
// Overrides FileSystemBase
virtual nsPIDOMWindow*
GetWindow() const override;
virtual void
GetRootName(nsAString& aRetval) const override;
virtual bool
IsSafeFile(nsIFile* aFile) const override;
virtual bool
IsSafeDirectory(Directory* aDir) const override;
private:
virtual ~OSFileSystem() {}
nsCOMPtr<nsPIDOMWindow> mWindow;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_OSFileSystem_h

View File

@ -11,6 +11,7 @@ EXPORTS.mozilla.dom += [
'FileSystemRequestParent.h',
'FileSystemTaskBase.h',
'FileSystemUtils.h',
'OSFileSystem.h',
]
UNIFIED_SOURCES += [
@ -25,6 +26,7 @@ UNIFIED_SOURCES += [
'FileSystemUtils.cpp',
'GetDirectoryListingTask.cpp',
'GetFileOrDirectoryTask.cpp',
'OSFileSystem.cpp',
'RemoveTask.cpp',
]