/* -*- 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 http://mozilla.org/MPL/2.0/. */#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"classnsIInputStream;classnsIOutputStream;namespacemozilla{classEventListenerManager;namespacedom{structDeviceStorageEnumerationParameters;classDOMCursor;classDOMRequest;classPromise;classDeviceStorageFileSystem;}// namespace domnamespaceipc{classFileDescriptor;}}// namespace mozillaclassDeviceStorageFilefinal:publicnsISupports{public:nsCOMPtr<nsIFile>mFile;nsStringmStorageType;nsStringmStorageName;nsStringmRootDir;nsStringmPath;boolmEditable;nsStringmMimeType;uint64_tmLength;uint64_tmLastModifiedDate;// Used when the path will be set later via SetPath.DeviceStorageFile(constnsAString&aStorageType,constnsAString&aStorageName);// Used for non-enumeration purposes.DeviceStorageFile(constnsAString&aStorageType,constnsAString&aStorageName,constnsAString&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(constnsAString&aStorageType,constnsAString&aStorageName,constnsAString&aRootDir,constnsAString&aPath);voidSetPath(constnsAString&aPath);voidSetEditable(boolaEditable);staticalready_AddRefed<DeviceStorageFile>CreateUnique(nsAString&aFileName,uint32_taFileType,uint32_taFileAttributes);NS_DECL_THREADSAFE_ISUPPORTSboolIsAvailable();voidGetFullPath(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.boolIsSafePath();boolIsSafePath(constnsAString&aPath);voidDump(constchar*label);nsresultRemove();nsresultWrite(nsIInputStream*aInputStream);nsresultWrite(InfallibleTArray<uint8_t>&bits);nsresultAppend(nsIInputStream*aInputStream);nsresultAppend(nsIInputStream*aInputStream,nsIOutputStream*aOutputStream);voidCollectFiles(nsTArray<nsRefPtr<DeviceStorageFile>>&aFiles,PRTimeaSince=0);voidcollectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile>>&aFiles,PRTimeaSince,nsAString&aRootPath);voidAccumDiskUsage(uint64_t*aPicturesSoFar,uint64_t*aVideosSoFar,uint64_t*aMusicSoFar,uint64_t*aTotalSoFar);voidGetDiskFreeSpace(int64_t*aSoFar);voidGetStatus(nsAString&aStatus);voidGetStorageStatus(nsAString&aStatus);voidDoFormat(nsAString&aStatus);voidDoMount(nsAString&aStatus);voidDoUnmount(nsAString&aStatus);staticvoidGetRootDirectoryForType(constnsAString&aStorageType,constnsAString&aStorageName,nsIFile**aFile);nsresultCalculateSizeAndModifiedDate();nsresultCalculateMimeType();nsresultCreateFileDescriptor(mozilla::ipc::FileDescriptor&aFileDescriptor);private:~DeviceStorageFile(){}voidInit();voidNormalizeFilePath();voidAppendRelativePath(constnsAString&aPath);voidAccumDirectoryUsage(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)*/classFileUpdateDispatcherfinal:publicnsIObserver{~FileUpdateDispatcher(){}public:NS_DECL_ISUPPORTSNS_DECL_NSIOBSERVERstaticFileUpdateDispatcher*GetSingleton();private:staticmozilla::StaticRefPtr<FileUpdateDispatcher>sSingleton;};classnsDOMDeviceStoragefinal:publicmozilla::DOMEventTargetHelper,publicnsIDOMDeviceStorage,publicnsIObserver{typedefmozilla::ErrorResultErrorResult;typedefmozilla::dom::DeviceStorageEnumerationParametersEnumerationParameters;typedefmozilla::dom::DOMCursorDOMCursor;typedefmozilla::dom::DOMRequestDOMRequest;typedefmozilla::dom::PromisePromise;typedefmozilla::dom::DeviceStorageFileSystemDeviceStorageFileSystem;public:typedefnsTArray<nsString>VolumeNameArray;NS_DECL_ISUPPORTS_INHERITEDNS_DECL_NSIDOMDEVICESTORAGENS_DECL_NSIOBSERVERNS_DECL_NSIDOMEVENTTARGETvirtualmozilla::EventListenerManager*GetExistingListenerManager()constoverride;virtualmozilla::EventListenerManager*GetOrCreateListenerManager()override;virtualvoidAddEventListener(constnsAString&aType,mozilla::dom::EventListener*aListener,boolaUseCapture,constmozilla::dom::Nullable<bool>&aWantsUntrusted,ErrorResult&aRv)override;virtualvoidRemoveEventListener(constnsAString&aType,mozilla::dom::EventListener*aListener,boolaUseCapture,ErrorResult&aRv)override;explicitnsDOMDeviceStorage(nsPIDOMWindow*aWindow);nsresultInit(nsPIDOMWindow*aWindow,constnsAString&aType,constnsAString&aVolName);boolIsAvailable();boolIsFullPath(constnsAString&aPath){returnaPath.Length()>0&&aPath.CharAt(0)=='/';}voidSetRootDirectoryForType(constnsAString&aType,constnsAString&aVolName);// WebIDLnsPIDOMWindow*GetParentObject()const{returnGetOwner();}virtualJSObject*WrapObject(JSContext*aCx)override;IMPL_EVENT_HANDLER(change)already_AddRefed<DOMRequest>Add(nsIDOMBlob*aBlob,ErrorResult&aRv);already_AddRefed<DOMRequest>AddNamed(nsIDOMBlob*aBlob,constnsAString&aPath,ErrorResult&aRv);already_AddRefed<DOMRequest>AppendNamed(nsIDOMBlob*aBlob,constnsAString&aPath,ErrorResult&aRv);already_AddRefed<DOMRequest>AddOrAppendNamed(nsIDOMBlob*aBlob,constnsAString&aPath,constint32_taRequestType,ErrorResult&aRv);already_AddRefed<DOMRequest>Get(constnsAString&aPath,ErrorResult&aRv){returnGetInternal(aPath,false,aRv);}already_AddRefed<DOMRequest>GetEditable(constnsAString&aPath,ErrorResult&aRv){returnGetInternal(aPath,true,aRv);}already_AddRefed<DOMRequest>Delete(constnsAString&aPath,ErrorResult&aRv);already_AddRefed<DOMCursor>Enumerate(constEnumerationParameters&aOptions,ErrorResult&aRv){returnEnumerate(NullString(),aOptions,aRv);}already_AddRefed<DOMCursor>Enumerate(constnsAString&aPath,constEnumerationParameters&aOptions,ErrorResult&aRv);already_AddRefed<DOMCursor>EnumerateEditable(constEnumerationParameters&aOptions,ErrorResult&aRv){returnEnumerateEditable(NullString(),aOptions,aRv);}already_AddRefed<DOMCursor>EnumerateEditable(constnsAString&aPath,constEnumerationParameters&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);boolCanBeMounted();boolCanBeFormatted();boolCanBeShared();boolIsRemovable();boolDefault();// Uses XPCOM GetStorageNamealready_AddRefed<Promise>GetRoot(ErrorResult&aRv);staticvoidCreateDeviceStorageFor(nsPIDOMWindow*aWin,constnsAString&aType,nsDOMDeviceStorage**aStore);staticvoidCreateDeviceStoragesFor(nsPIDOMWindow*aWin,constnsAString&aType,nsTArray<nsRefPtr<nsDOMDeviceStorage>>&aStores);voidShutdown();staticvoidGetOrderedVolumeNames(nsTArray<nsString>&aVolumeNames);staticvoidGetDefaultStorageName(constnsAString&aStorageType,nsAString&aStorageName);staticboolParseFullPath(constnsAString&aFullPath,nsAString&aOutStorageName,nsAString&aOutStoragePath);private:~nsDOMDeviceStorage();already_AddRefed<DOMRequest>GetInternal(constnsAString&aPath,boolaEditable,ErrorResult&aRv);voidGetInternal(nsPIDOMWindow*aWin,constnsAString&aPath,DOMRequest*aRequest,boolaEditable);voidDeleteInternal(nsPIDOMWindow*aWin,constnsAString&aPath,DOMRequest*aRequest);already_AddRefed<DOMCursor>EnumerateInternal(constnsAString&aName,constEnumerationParameters&aOptions,boolaEditable,ErrorResult&aRv);nsStringmStorageType;nsCOMPtr<nsIFile>mRootDirectory;nsStringmStorageName;boolmIsShareable;boolmIsRemovable;already_AddRefed<nsDOMDeviceStorage>GetStorage(constnsAString&aFullPath,nsAString&aOutStoragePath);already_AddRefed<nsDOMDeviceStorage>GetStorageByName(constnsAString&aStorageName);nsCOMPtr<nsIPrincipal>mPrincipal;boolmIsWatchingFile;boolmAllowedToWatchFile;nsresultNotify(constchar*aReason,classDeviceStorageFile*aFile);friendclassWatchFileEvent;friendclassDeviceStorageRequest;staticmozilla::StaticAutoPtr<nsTArray<nsString>>sVolumeNameCache;#ifdef MOZ_WIDGET_GONKnsStringmLastStatus;nsStringmLastStorageStatus;voidDispatchStatusChangeEvent(nsAString&aStatus);voidDispatchStorageStatusChangeEvent(nsAString&aStorageStatus);#endif// nsIDOMDeviceStorage.typeenum{DEVICE_STORAGE_TYPE_DEFAULT=0,DEVICE_STORAGE_TYPE_SHARED,DEVICE_STORAGE_TYPE_EXTERNAL};nsRefPtr<DeviceStorageFileSystem>mFileSystem;};#endif