1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/devicestorage/DeviceStorage.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,341 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 sw=2 et tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef DeviceStorage_h 1.11 +#define DeviceStorage_h 1.12 + 1.13 +#include "nsIDOMDeviceStorage.h" 1.14 +#include "nsIFile.h" 1.15 +#include "nsIPrincipal.h" 1.16 +#include "nsIObserver.h" 1.17 +#include "mozilla/DOMEventTargetHelper.h" 1.18 +#include "mozilla/RefPtr.h" 1.19 +#include "mozilla/StaticPtr.h" 1.20 +#include "mozilla/dom/DOMRequest.h" 1.21 + 1.22 +#define DEVICESTORAGE_PICTURES "pictures" 1.23 +#define DEVICESTORAGE_VIDEOS "videos" 1.24 +#define DEVICESTORAGE_MUSIC "music" 1.25 +#define DEVICESTORAGE_APPS "apps" 1.26 +#define DEVICESTORAGE_SDCARD "sdcard" 1.27 +#define DEVICESTORAGE_CRASHES "crashes" 1.28 + 1.29 +class DeviceStorageFile; 1.30 +class nsIInputStream; 1.31 + 1.32 +namespace mozilla { 1.33 +class EventListenerManager; 1.34 +namespace dom { 1.35 +class DeviceStorageEnumerationParameters; 1.36 +class DOMCursor; 1.37 +class DOMRequest; 1.38 +class Promise; 1.39 +class DeviceStorageFileSystem; 1.40 +} // namespace dom 1.41 +namespace ipc { 1.42 +class FileDescriptor; 1.43 +} 1.44 +} // namespace mozilla 1.45 + 1.46 +class DeviceStorageFile MOZ_FINAL 1.47 + : public nsISupports { 1.48 +public: 1.49 + nsCOMPtr<nsIFile> mFile; 1.50 + nsString mStorageType; 1.51 + nsString mStorageName; 1.52 + nsString mRootDir; 1.53 + nsString mPath; 1.54 + bool mEditable; 1.55 + nsString mMimeType; 1.56 + uint64_t mLength; 1.57 + uint64_t mLastModifiedDate; 1.58 + 1.59 + // Used when the path will be set later via SetPath. 1.60 + DeviceStorageFile(const nsAString& aStorageType, 1.61 + const nsAString& aStorageName); 1.62 + // Used for non-enumeration purposes. 1.63 + DeviceStorageFile(const nsAString& aStorageType, 1.64 + const nsAString& aStorageName, 1.65 + const nsAString& aPath); 1.66 + // Used for enumerations. When you call Enumerate, you can pass in a 1.67 + // directory to enumerate and the results that are returned are relative to 1.68 + // that directory, files related to an enumeration need to know the "root of 1.69 + // the enumeration" directory. 1.70 + DeviceStorageFile(const nsAString& aStorageType, 1.71 + const nsAString& aStorageName, 1.72 + const nsAString& aRootDir, 1.73 + const nsAString& aPath); 1.74 + 1.75 + void SetPath(const nsAString& aPath); 1.76 + void SetEditable(bool aEditable); 1.77 + 1.78 + static already_AddRefed<DeviceStorageFile> 1.79 + CreateUnique(nsAString& aFileName, 1.80 + uint32_t aFileType, 1.81 + uint32_t aFileAttributes); 1.82 + 1.83 + NS_DECL_THREADSAFE_ISUPPORTS 1.84 + 1.85 + bool IsAvailable(); 1.86 + void GetFullPath(nsAString& aFullPath); 1.87 + 1.88 + // we want to make sure that the names of file can't reach 1.89 + // outside of the type of storage the user asked for. 1.90 + bool IsSafePath(); 1.91 + bool IsSafePath(const nsAString& aPath); 1.92 + 1.93 + void Dump(const char* label); 1.94 + 1.95 + nsresult Remove(); 1.96 + nsresult Write(nsIInputStream* aInputStream); 1.97 + nsresult Write(InfallibleTArray<uint8_t>& bits); 1.98 + void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> >& aFiles, 1.99 + PRTime aSince = 0); 1.100 + void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> >& aFiles, 1.101 + PRTime aSince, nsAString& aRootPath); 1.102 + 1.103 + void AccumDiskUsage(uint64_t* aPicturesSoFar, uint64_t* aVideosSoFar, 1.104 + uint64_t* aMusicSoFar, uint64_t* aTotalSoFar); 1.105 + 1.106 + void GetDiskFreeSpace(int64_t* aSoFar); 1.107 + void GetStatus(nsAString& aStatus); 1.108 + void GetStorageStatus(nsAString& aStatus); 1.109 + void DoFormat(nsAString& aStatus); 1.110 + void DoMount(nsAString& aStatus); 1.111 + void DoUnmount(nsAString& aStatus); 1.112 + static void GetRootDirectoryForType(const nsAString& aStorageType, 1.113 + const nsAString& aStorageName, 1.114 + nsIFile** aFile); 1.115 + 1.116 + nsresult CalculateSizeAndModifiedDate(); 1.117 + nsresult CalculateMimeType(); 1.118 + nsresult CreateFileDescriptor(mozilla::ipc::FileDescriptor& aFileDescriptor); 1.119 + 1.120 +private: 1.121 + void Init(); 1.122 + void NormalizeFilePath(); 1.123 + void AppendRelativePath(const nsAString& aPath); 1.124 + void AccumDirectoryUsage(nsIFile* aFile, 1.125 + uint64_t* aPicturesSoFar, 1.126 + uint64_t* aVideosSoFar, 1.127 + uint64_t* aMusicSoFar, 1.128 + uint64_t* aTotalSoFar); 1.129 +}; 1.130 + 1.131 +/* 1.132 + The FileUpdateDispatcher converts file-watcher-notify 1.133 + observer events to file-watcher-update events. This is 1.134 + used to be able to broadcast events from one child to 1.135 + another child in B2G. (f.e., if one child decides to add 1.136 + a file, we want to be able to able to send a onchange 1.137 + notifications to every other child watching that device 1.138 + storage object). 1.139 + 1.140 + We create this object (via GetSingleton) in two places: 1.141 + * ContentParent::Init (for IPC) 1.142 + * nsDOMDeviceStorage::Init (for non-ipc) 1.143 +*/ 1.144 +class FileUpdateDispatcher MOZ_FINAL 1.145 + : public nsIObserver 1.146 +{ 1.147 + public: 1.148 + NS_DECL_ISUPPORTS 1.149 + NS_DECL_NSIOBSERVER 1.150 + 1.151 + static FileUpdateDispatcher* GetSingleton(); 1.152 + private: 1.153 + static mozilla::StaticRefPtr<FileUpdateDispatcher> sSingleton; 1.154 +}; 1.155 + 1.156 +class nsDOMDeviceStorage MOZ_FINAL 1.157 + : public mozilla::DOMEventTargetHelper 1.158 + , public nsIDOMDeviceStorage 1.159 + , public nsIObserver 1.160 +{ 1.161 + typedef mozilla::ErrorResult ErrorResult; 1.162 + typedef mozilla::dom::DeviceStorageEnumerationParameters 1.163 + EnumerationParameters; 1.164 + typedef mozilla::dom::DOMCursor DOMCursor; 1.165 + typedef mozilla::dom::DOMRequest DOMRequest; 1.166 + typedef mozilla::dom::Promise Promise; 1.167 + typedef mozilla::dom::DeviceStorageFileSystem DeviceStorageFileSystem; 1.168 +public: 1.169 + typedef nsTArray<nsString> VolumeNameArray; 1.170 + 1.171 + NS_DECL_ISUPPORTS_INHERITED 1.172 + NS_DECL_NSIDOMDEVICESTORAGE 1.173 + 1.174 + NS_DECL_NSIOBSERVER 1.175 + NS_DECL_NSIDOMEVENTTARGET 1.176 + 1.177 + virtual mozilla::EventListenerManager* 1.178 + GetExistingListenerManager() const MOZ_OVERRIDE; 1.179 + virtual mozilla::EventListenerManager* 1.180 + GetOrCreateListenerManager() MOZ_OVERRIDE; 1.181 + 1.182 + virtual void 1.183 + AddEventListener(const nsAString& aType, 1.184 + mozilla::dom::EventListener* aListener, 1.185 + bool aUseCapture, 1.186 + const mozilla::dom::Nullable<bool>& aWantsUntrusted, 1.187 + ErrorResult& aRv) MOZ_OVERRIDE; 1.188 + 1.189 + virtual void RemoveEventListener(const nsAString& aType, 1.190 + mozilla::dom::EventListener* aListener, 1.191 + bool aUseCapture, 1.192 + ErrorResult& aRv) MOZ_OVERRIDE; 1.193 + 1.194 + nsDOMDeviceStorage(nsPIDOMWindow* aWindow); 1.195 + 1.196 + nsresult Init(nsPIDOMWindow* aWindow, const nsAString& aType, 1.197 + const nsAString& aVolName); 1.198 + 1.199 + bool IsAvailable(); 1.200 + bool IsFullPath(const nsAString& aPath) 1.201 + { 1.202 + return aPath.Length() > 0 && aPath.CharAt(0) == '/'; 1.203 + } 1.204 + 1.205 + void SetRootDirectoryForType(const nsAString& aType, 1.206 + const nsAString& aVolName); 1.207 + 1.208 + // WebIDL 1.209 + nsPIDOMWindow* 1.210 + GetParentObject() const 1.211 + { 1.212 + return GetOwner(); 1.213 + } 1.214 + virtual JSObject* 1.215 + WrapObject(JSContext* aCx) MOZ_OVERRIDE; 1.216 + 1.217 + IMPL_EVENT_HANDLER(change) 1.218 + 1.219 + already_AddRefed<DOMRequest> 1.220 + Add(nsIDOMBlob* aBlob, ErrorResult& aRv); 1.221 + already_AddRefed<DOMRequest> 1.222 + AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, ErrorResult& aRv); 1.223 + 1.224 + already_AddRefed<DOMRequest> 1.225 + Get(const nsAString& aPath, ErrorResult& aRv) 1.226 + { 1.227 + return GetInternal(aPath, false, aRv); 1.228 + } 1.229 + already_AddRefed<DOMRequest> 1.230 + GetEditable(const nsAString& aPath, ErrorResult& aRv) 1.231 + { 1.232 + return GetInternal(aPath, true, aRv); 1.233 + } 1.234 + already_AddRefed<DOMRequest> 1.235 + Delete(const nsAString& aPath, ErrorResult& aRv); 1.236 + 1.237 + already_AddRefed<DOMCursor> 1.238 + Enumerate(const EnumerationParameters& aOptions, ErrorResult& aRv) 1.239 + { 1.240 + return Enumerate(NullString(), aOptions, aRv); 1.241 + } 1.242 + already_AddRefed<DOMCursor> 1.243 + Enumerate(const nsAString& aPath, const EnumerationParameters& aOptions, 1.244 + ErrorResult& aRv); 1.245 + already_AddRefed<DOMCursor> 1.246 + EnumerateEditable(const EnumerationParameters& aOptions, ErrorResult& aRv) 1.247 + { 1.248 + return EnumerateEditable(NullString(), aOptions, aRv); 1.249 + } 1.250 + already_AddRefed<DOMCursor> 1.251 + EnumerateEditable(const nsAString& aPath, 1.252 + const EnumerationParameters& aOptions, ErrorResult& aRv); 1.253 + 1.254 + already_AddRefed<DOMRequest> FreeSpace(ErrorResult& aRv); 1.255 + already_AddRefed<DOMRequest> UsedSpace(ErrorResult& aRv); 1.256 + already_AddRefed<DOMRequest> Available(ErrorResult& aRv); 1.257 + already_AddRefed<DOMRequest> Format(ErrorResult& aRv); 1.258 + already_AddRefed<DOMRequest> StorageStatus(ErrorResult& aRv); 1.259 + already_AddRefed<DOMRequest> Mount(ErrorResult& aRv); 1.260 + already_AddRefed<DOMRequest> Unmount(ErrorResult& aRv); 1.261 + 1.262 + bool Default(); 1.263 + 1.264 + // Uses XPCOM GetStorageName 1.265 + 1.266 + already_AddRefed<Promise> 1.267 + GetRoot(); 1.268 + 1.269 + static void 1.270 + CreateDeviceStorageFor(nsPIDOMWindow* aWin, 1.271 + const nsAString& aType, 1.272 + nsDOMDeviceStorage** aStore); 1.273 + 1.274 + static void 1.275 + CreateDeviceStoragesFor(nsPIDOMWindow* aWin, 1.276 + const nsAString& aType, 1.277 + nsTArray<nsRefPtr<nsDOMDeviceStorage> >& aStores); 1.278 + 1.279 + void Shutdown(); 1.280 + 1.281 + static void GetOrderedVolumeNames(nsTArray<nsString>& aVolumeNames); 1.282 + 1.283 + static void GetDefaultStorageName(const nsAString& aStorageType, 1.284 + nsAString &aStorageName); 1.285 + 1.286 + static bool ParseFullPath(const nsAString& aFullPath, 1.287 + nsAString& aOutStorageName, 1.288 + nsAString& aOutStoragePath); 1.289 +private: 1.290 + ~nsDOMDeviceStorage(); 1.291 + 1.292 + already_AddRefed<DOMRequest> 1.293 + GetInternal(const nsAString& aPath, bool aEditable, ErrorResult& aRv); 1.294 + 1.295 + void 1.296 + GetInternal(nsPIDOMWindow* aWin, const nsAString& aPath, DOMRequest* aRequest, 1.297 + bool aEditable); 1.298 + 1.299 + void 1.300 + DeleteInternal(nsPIDOMWindow* aWin, const nsAString& aPath, 1.301 + DOMRequest* aRequest); 1.302 + 1.303 + already_AddRefed<DOMCursor> 1.304 + EnumerateInternal(const nsAString& aName, 1.305 + const EnumerationParameters& aOptions, bool aEditable, 1.306 + ErrorResult& aRv); 1.307 + 1.308 + nsString mStorageType; 1.309 + nsCOMPtr<nsIFile> mRootDirectory; 1.310 + nsString mStorageName; 1.311 + 1.312 + already_AddRefed<nsDOMDeviceStorage> GetStorage(const nsAString& aFullPath, 1.313 + nsAString& aOutStoragePath); 1.314 + already_AddRefed<nsDOMDeviceStorage> 1.315 + GetStorageByName(const nsAString &aStorageName); 1.316 + 1.317 + nsCOMPtr<nsIPrincipal> mPrincipal; 1.318 + 1.319 + bool mIsWatchingFile; 1.320 + bool mAllowedToWatchFile; 1.321 + 1.322 + nsresult Notify(const char* aReason, class DeviceStorageFile* aFile); 1.323 + 1.324 + friend class WatchFileEvent; 1.325 + friend class DeviceStorageRequest; 1.326 + 1.327 + static mozilla::StaticAutoPtr<nsTArray<nsString>> sVolumeNameCache; 1.328 + 1.329 +#ifdef MOZ_WIDGET_GONK 1.330 + nsString mLastStatus; 1.331 + void DispatchMountChangeEvent(nsAString& aVolumeStatus); 1.332 +#endif 1.333 + 1.334 + // nsIDOMDeviceStorage.type 1.335 + enum { 1.336 + DEVICE_STORAGE_TYPE_DEFAULT = 0, 1.337 + DEVICE_STORAGE_TYPE_SHARED, 1.338 + DEVICE_STORAGE_TYPE_EXTERNAL 1.339 + }; 1.340 + 1.341 + nsRefPtr<DeviceStorageFileSystem> mFileSystem; 1.342 +}; 1.343 + 1.344 +#endif