author Ehsan Akhgari <>
Wed, 25 Mar 2015 12:42:35 -0400
changeset 245309 a20c7910a82fa2df2f3398c1108d102bac9128b0
parent 234605 4995c6fc739eccf79fe741172b10bb9710cb9505
permissions -rw-r--r--
Bug 1145631 - Part 1: Replace MOZ_OVERRIDE and MOZ_FINAL with override and final in the tree; r=froydnj This patch was automatically generated using the following script: function convert() { echo "Converting $1 to $2..." find . \ ! -wholename "*/.git*" \ ! -wholename "obj-ff-dbg*" \ -type f \ \( -iname "*.cpp" \ -o -iname "*.h" \ -o -iname "*.c" \ -o -iname "*.cc" \ -o -iname "*.idl" \ -o -iname "*.ipdl" \ -o -iname "*.ipdlh" \ -o -iname "*.mm" \) | \ xargs -n 1 sed -i -e "s/\b$1\b/$2/g" } convert MOZ_OVERRIDE override convert MOZ_FINAL final

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et 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 */

#ifndef DeviceStorage_h
#define DeviceStorage_h

#include "nsIDOMDeviceStorage.h"
#include "nsIFile.h"
#include "nsIPrincipal.h"
#include "nsIObserver.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/DOMRequest.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;

namespace mozilla {
class EventListenerManager;
namespace dom {
struct DeviceStorageEnumerationParameters;
class DOMCursor;
class DOMRequest;
class Promise;
class DeviceStorageFileSystem;
} // namespace dom
namespace ipc {
class FileDescriptor;
} // namespace mozilla

class DeviceStorageFile final
  : public nsISupports {
  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);


  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();
  bool IsSafePath(const nsAString& aPath);

  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<nsRefPtr<DeviceStorageFile> >& aFiles,
                    PRTime aSince = 0);
  void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> >& aFiles,
                            PRTime aSince, nsAString& aRootPath);

  void AccumDiskUsage(uint64_t* aPicturesSoFar, uint64_t* aVideosSoFar,
                      uint64_t* aMusicSoFar, uint64_t* aTotalSoFar);

  void GetDiskFreeSpace(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);

  ~DeviceStorageFile() {}
  void Init();
  void NormalizeFilePath();
  void AppendRelativePath(const nsAString& aPath);
  void AccumDirectoryUsage(nsIFile* aFile,
                           uint64_t* aPicturesSoFar,
                           uint64_t* aVideosSoFar,
                           uint64_t* aMusicSoFar,
                           uint64_t* aTotalSoFar);

  The FileUpdateDispatcher converts file-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).

  We create this object (via GetSingleton) in two places:
    * ContentParent::Init (for IPC)
    * nsDOMDeviceStorage::Init (for non-ipc)
class FileUpdateDispatcher final
  : public nsIObserver
  ~FileUpdateDispatcher() {}


  static FileUpdateDispatcher* GetSingleton();
  static mozilla::StaticRefPtr<FileUpdateDispatcher> sSingleton;

class nsDOMDeviceStorage final
  : public mozilla::DOMEventTargetHelper
  , public nsIDOMDeviceStorage
  , public nsIObserver
  typedef mozilla::ErrorResult ErrorResult;
  typedef mozilla::dom::DeviceStorageEnumerationParameters
  typedef mozilla::dom::DOMCursor DOMCursor;
  typedef mozilla::dom::DOMRequest DOMRequest;
  typedef mozilla::dom::Promise Promise;
  typedef mozilla::dom::DeviceStorageFileSystem DeviceStorageFileSystem;
  typedef nsTArray<nsString> VolumeNameArray;



  virtual mozilla::EventListenerManager*
    GetExistingListenerManager() const override;
  virtual mozilla::EventListenerManager*
    GetOrCreateListenerManager() override;

  virtual void
  AddEventListener(const nsAString& aType,
                   mozilla::dom::EventListener* aListener,
                   bool aUseCapture,
                   const mozilla::dom::Nullable<bool>& aWantsUntrusted,
                   ErrorResult& aRv) override;

  virtual void RemoveEventListener(const nsAString& aType,
                                   mozilla::dom::EventListener* aListener,
                                   bool aUseCapture,
                                   ErrorResult& aRv) override;

  explicit nsDOMDeviceStorage(nsPIDOMWindow* aWindow);

  nsresult Init(nsPIDOMWindow* 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
  GetParentObject() const
    return GetOwner();
  virtual JSObject*
  WrapObject(JSContext* aCx) override;


  Add(nsIDOMBlob* aBlob, ErrorResult& aRv);
  AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, ErrorResult& aRv);

  AppendNamed(nsIDOMBlob* aBlob, const nsAString& aPath, ErrorResult& aRv);

  AddOrAppendNamed(nsIDOMBlob* aBlob, const nsAString& aPath,
                   const int32_t aRequestType, ErrorResult& aRv);

  Get(const nsAString& aPath, ErrorResult& aRv)
    return GetInternal(aPath, false, aRv);
  GetEditable(const nsAString& aPath, ErrorResult& aRv)
    return GetInternal(aPath, true, aRv);
  Delete(const nsAString& aPath, ErrorResult& aRv);

  Enumerate(const EnumerationParameters& aOptions, ErrorResult& aRv)
    return Enumerate(NullString(), aOptions, aRv);
  Enumerate(const nsAString& aPath, const EnumerationParameters& aOptions,
            ErrorResult& aRv);
  EnumerateEditable(const EnumerationParameters& aOptions, ErrorResult& aRv)
    return EnumerateEditable(NullString(), aOptions, aRv);
  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);

  bool CanBeMounted();
  bool CanBeFormatted();
  bool CanBeShared();
  bool IsRemovable();
  bool Default();

  // Uses XPCOM GetStorageName

  GetRoot(ErrorResult& aRv);

  static void
  CreateDeviceStorageFor(nsPIDOMWindow* aWin,
                         const nsAString& aType,
                         nsDOMDeviceStorage** aStore);

  static void
  CreateDeviceStoragesFor(nsPIDOMWindow* aWin,
                          const nsAString& aType,
                          nsTArray<nsRefPtr<nsDOMDeviceStorage> >& aStores);

  void Shutdown();

  static void GetOrderedVolumeNames(nsTArray<nsString>& aVolumeNames);

  static void GetDefaultStorageName(const nsAString& aStorageType,
                                    nsAString &aStorageName);

  static bool ParseFullPath(const nsAString& aFullPath,
                            nsAString& aOutStorageName,
                            nsAString& aOutStoragePath);

  GetInternal(const nsAString& aPath, bool aEditable, ErrorResult& aRv);

  GetInternal(nsPIDOMWindow* aWin, const nsAString& aPath, DOMRequest* aRequest,
              bool aEditable);

  DeleteInternal(nsPIDOMWindow* aWin, const nsAString& aPath,
                 DOMRequest* aRequest);

  EnumerateInternal(const nsAString& aName,
                    const EnumerationParameters& aOptions, bool aEditable,
                    ErrorResult& aRv);

  nsString mStorageType;
  nsCOMPtr<nsIFile> mRootDirectory;
  nsString mStorageName;
  bool mIsShareable;
  bool mIsRemovable;

  already_AddRefed<nsDOMDeviceStorage> GetStorage(const nsAString& aFullPath,
                                                  nsAString& aOutStoragePath);
    GetStorageByName(const nsAString &aStorageName);

  nsCOMPtr<nsIPrincipal> mPrincipal;

  bool mIsWatchingFile;
  bool mAllowedToWatchFile;

  nsresult Notify(const char* aReason, class DeviceStorageFile* aFile);

  friend class WatchFileEvent;
  friend class DeviceStorageRequest;

  static mozilla::StaticAutoPtr<nsTArray<nsString>> sVolumeNameCache;

  nsString mLastStatus;
  nsString mLastStorageStatus;
  void DispatchStatusChangeEvent(nsAString& aStatus);
  void DispatchStorageStatusChangeEvent(nsAString& aStorageStatus);

  // nsIDOMDeviceStorage.type
  enum {

  nsRefPtr<DeviceStorageFileSystem> mFileSystem;