1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DeviceStorage_h
8 #define DeviceStorage_h
10 #include "nsIDOMDeviceStorage.h"
12 #include "nsIPrincipal.h"
13 #include "nsIObserver.h"
14 #include "mozilla/DOMEventTargetHelper.h"
15 #include "mozilla/RefPtr.h"
16 #include "mozilla/StaticPtr.h"
17 #include "mozilla/dom/DOMRequest.h"
19 #define DEVICESTORAGE_PICTURES "pictures"
20 #define DEVICESTORAGE_VIDEOS "videos"
21 #define DEVICESTORAGE_MUSIC "music"
22 #define DEVICESTORAGE_APPS "apps"
23 #define DEVICESTORAGE_SDCARD "sdcard"
24 #define DEVICESTORAGE_CRASHES "crashes"
27 class nsIOutputStream
;
30 class EventListenerManager
;
32 struct DeviceStorageEnumerationParameters
;
36 class DeviceStorageFileSystem
;
41 } // namespace mozilla
43 class DeviceStorageFile MOZ_FINAL
44 : public nsISupports
{
46 nsCOMPtr
<nsIFile
> mFile
;
47 nsString mStorageType
;
48 nsString mStorageName
;
54 uint64_t mLastModifiedDate
;
56 // Used when the path will be set later via SetPath.
57 DeviceStorageFile(const nsAString
& aStorageType
,
58 const nsAString
& aStorageName
);
59 // Used for non-enumeration purposes.
60 DeviceStorageFile(const nsAString
& aStorageType
,
61 const nsAString
& aStorageName
,
62 const nsAString
& aPath
);
63 // Used for enumerations. When you call Enumerate, you can pass in a
64 // directory to enumerate and the results that are returned are relative to
65 // that directory, files related to an enumeration need to know the "root of
66 // the enumeration" directory.
67 DeviceStorageFile(const nsAString
& aStorageType
,
68 const nsAString
& aStorageName
,
69 const nsAString
& aRootDir
,
70 const nsAString
& aPath
);
72 void SetPath(const nsAString
& aPath
);
73 void SetEditable(bool aEditable
);
75 static already_AddRefed
<DeviceStorageFile
>
76 CreateUnique(nsAString
& aFileName
,
78 uint32_t aFileAttributes
);
80 NS_DECL_THREADSAFE_ISUPPORTS
83 void GetFullPath(nsAString
& aFullPath
);
85 // we want to make sure that the names of file can't reach
86 // outside of the type of storage the user asked for.
88 bool IsSafePath(const nsAString
& aPath
);
90 void Dump(const char* label
);
93 nsresult
Write(nsIInputStream
* aInputStream
);
94 nsresult
Write(InfallibleTArray
<uint8_t>& bits
);
95 nsresult
Append(nsIInputStream
* aInputStream
);
96 nsresult
Append(nsIInputStream
* aInputStream
,
97 nsIOutputStream
* aOutputStream
);
98 void CollectFiles(nsTArray
<nsRefPtr
<DeviceStorageFile
> >& aFiles
,
100 void collectFilesInternal(nsTArray
<nsRefPtr
<DeviceStorageFile
> >& aFiles
,
101 PRTime aSince
, nsAString
& aRootPath
);
103 void AccumDiskUsage(uint64_t* aPicturesSoFar
, uint64_t* aVideosSoFar
,
104 uint64_t* aMusicSoFar
, uint64_t* aTotalSoFar
);
106 void GetDiskFreeSpace(int64_t* aSoFar
);
107 void GetStatus(nsAString
& aStatus
);
108 void GetStorageStatus(nsAString
& aStatus
);
109 void DoFormat(nsAString
& aStatus
);
110 void DoMount(nsAString
& aStatus
);
111 void DoUnmount(nsAString
& aStatus
);
112 static void GetRootDirectoryForType(const nsAString
& aStorageType
,
113 const nsAString
& aStorageName
,
116 nsresult
CalculateSizeAndModifiedDate();
117 nsresult
CalculateMimeType();
118 nsresult
CreateFileDescriptor(mozilla::ipc::FileDescriptor
& aFileDescriptor
);
121 ~DeviceStorageFile() {}
123 void NormalizeFilePath();
124 void AppendRelativePath(const nsAString
& aPath
);
125 void AccumDirectoryUsage(nsIFile
* aFile
,
126 uint64_t* aPicturesSoFar
,
127 uint64_t* aVideosSoFar
,
128 uint64_t* aMusicSoFar
,
129 uint64_t* aTotalSoFar
);
133 The FileUpdateDispatcher converts file-watcher-notify
134 observer events to file-watcher-update events. This is
135 used to be able to broadcast events from one child to
136 another child in B2G. (f.e., if one child decides to add
137 a file, we want to be able to able to send a onchange
138 notifications to every other child watching that device
141 We create this object (via GetSingleton) in two places:
142 * ContentParent::Init (for IPC)
143 * nsDOMDeviceStorage::Init (for non-ipc)
145 class FileUpdateDispatcher MOZ_FINAL
148 ~FileUpdateDispatcher() {}
154 static FileUpdateDispatcher
* GetSingleton();
156 static mozilla::StaticRefPtr
<FileUpdateDispatcher
> sSingleton
;
159 class nsDOMDeviceStorage MOZ_FINAL
160 : public mozilla::DOMEventTargetHelper
161 , public nsIDOMDeviceStorage
164 typedef mozilla::ErrorResult ErrorResult
;
165 typedef mozilla::dom::DeviceStorageEnumerationParameters
166 EnumerationParameters
;
167 typedef mozilla::dom::DOMCursor DOMCursor
;
168 typedef mozilla::dom::DOMRequest DOMRequest
;
169 typedef mozilla::dom::Promise Promise
;
170 typedef mozilla::dom::DeviceStorageFileSystem DeviceStorageFileSystem
;
172 typedef nsTArray
<nsString
> VolumeNameArray
;
174 NS_DECL_ISUPPORTS_INHERITED
175 NS_DECL_NSIDOMDEVICESTORAGE
178 NS_DECL_NSIDOMEVENTTARGET
180 virtual mozilla::EventListenerManager
*
181 GetExistingListenerManager() const MOZ_OVERRIDE
;
182 virtual mozilla::EventListenerManager
*
183 GetOrCreateListenerManager() MOZ_OVERRIDE
;
186 AddEventListener(const nsAString
& aType
,
187 mozilla::dom::EventListener
* aListener
,
189 const mozilla::dom::Nullable
<bool>& aWantsUntrusted
,
190 ErrorResult
& aRv
) MOZ_OVERRIDE
;
192 virtual void RemoveEventListener(const nsAString
& aType
,
193 mozilla::dom::EventListener
* aListener
,
195 ErrorResult
& aRv
) MOZ_OVERRIDE
;
197 explicit nsDOMDeviceStorage(nsPIDOMWindow
* aWindow
);
199 nsresult
Init(nsPIDOMWindow
* aWindow
, const nsAString
& aType
,
200 const nsAString
& aVolName
);
203 bool IsFullPath(const nsAString
& aPath
)
205 return aPath
.Length() > 0 && aPath
.CharAt(0) == '/';
208 void SetRootDirectoryForType(const nsAString
& aType
,
209 const nsAString
& aVolName
);
213 GetParentObject() const
218 WrapObject(JSContext
* aCx
) MOZ_OVERRIDE
;
220 IMPL_EVENT_HANDLER(change
)
222 already_AddRefed
<DOMRequest
>
223 Add(nsIDOMBlob
* aBlob
, ErrorResult
& aRv
);
224 already_AddRefed
<DOMRequest
>
225 AddNamed(nsIDOMBlob
* aBlob
, const nsAString
& aPath
, ErrorResult
& aRv
);
227 already_AddRefed
<DOMRequest
>
228 AppendNamed(nsIDOMBlob
* aBlob
, const nsAString
& aPath
, ErrorResult
& aRv
);
230 already_AddRefed
<DOMRequest
>
231 AddOrAppendNamed(nsIDOMBlob
* aBlob
, const nsAString
& aPath
,
232 const int32_t aRequestType
, ErrorResult
& aRv
);
234 already_AddRefed
<DOMRequest
>
235 Get(const nsAString
& aPath
, ErrorResult
& aRv
)
237 return GetInternal(aPath
, false, aRv
);
239 already_AddRefed
<DOMRequest
>
240 GetEditable(const nsAString
& aPath
, ErrorResult
& aRv
)
242 return GetInternal(aPath
, true, aRv
);
244 already_AddRefed
<DOMRequest
>
245 Delete(const nsAString
& aPath
, ErrorResult
& aRv
);
247 already_AddRefed
<DOMCursor
>
248 Enumerate(const EnumerationParameters
& aOptions
, ErrorResult
& aRv
)
250 return Enumerate(NullString(), aOptions
, aRv
);
252 already_AddRefed
<DOMCursor
>
253 Enumerate(const nsAString
& aPath
, const EnumerationParameters
& aOptions
,
255 already_AddRefed
<DOMCursor
>
256 EnumerateEditable(const EnumerationParameters
& aOptions
, ErrorResult
& aRv
)
258 return EnumerateEditable(NullString(), aOptions
, aRv
);
260 already_AddRefed
<DOMCursor
>
261 EnumerateEditable(const nsAString
& aPath
,
262 const EnumerationParameters
& aOptions
, ErrorResult
& aRv
);
264 already_AddRefed
<DOMRequest
> FreeSpace(ErrorResult
& aRv
);
265 already_AddRefed
<DOMRequest
> UsedSpace(ErrorResult
& aRv
);
266 already_AddRefed
<DOMRequest
> Available(ErrorResult
& aRv
);
267 already_AddRefed
<DOMRequest
> Format(ErrorResult
& aRv
);
268 already_AddRefed
<DOMRequest
> StorageStatus(ErrorResult
& aRv
);
269 already_AddRefed
<DOMRequest
> Mount(ErrorResult
& aRv
);
270 already_AddRefed
<DOMRequest
> Unmount(ErrorResult
& aRv
);
273 bool CanBeFormatted();
277 // Uses XPCOM GetStorageName
279 already_AddRefed
<Promise
>
280 GetRoot(ErrorResult
& aRv
);
283 CreateDeviceStorageFor(nsPIDOMWindow
* aWin
,
284 const nsAString
& aType
,
285 nsDOMDeviceStorage
** aStore
);
288 CreateDeviceStoragesFor(nsPIDOMWindow
* aWin
,
289 const nsAString
& aType
,
290 nsTArray
<nsRefPtr
<nsDOMDeviceStorage
> >& aStores
);
294 static void GetOrderedVolumeNames(nsTArray
<nsString
>& aVolumeNames
);
296 static void GetDefaultStorageName(const nsAString
& aStorageType
,
297 nsAString
&aStorageName
);
299 static bool ParseFullPath(const nsAString
& aFullPath
,
300 nsAString
& aOutStorageName
,
301 nsAString
& aOutStoragePath
);
303 ~nsDOMDeviceStorage();
305 already_AddRefed
<DOMRequest
>
306 GetInternal(const nsAString
& aPath
, bool aEditable
, ErrorResult
& aRv
);
309 GetInternal(nsPIDOMWindow
* aWin
, const nsAString
& aPath
, DOMRequest
* aRequest
,
313 DeleteInternal(nsPIDOMWindow
* aWin
, const nsAString
& aPath
,
314 DOMRequest
* aRequest
);
316 already_AddRefed
<DOMCursor
>
317 EnumerateInternal(const nsAString
& aName
,
318 const EnumerationParameters
& aOptions
, bool aEditable
,
321 nsString mStorageType
;
322 nsCOMPtr
<nsIFile
> mRootDirectory
;
323 nsString mStorageName
;
326 already_AddRefed
<nsDOMDeviceStorage
> GetStorage(const nsAString
& aFullPath
,
327 nsAString
& aOutStoragePath
);
328 already_AddRefed
<nsDOMDeviceStorage
>
329 GetStorageByName(const nsAString
&aStorageName
);
331 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
333 bool mIsWatchingFile
;
334 bool mAllowedToWatchFile
;
336 nsresult
Notify(const char* aReason
, class DeviceStorageFile
* aFile
);
338 friend class WatchFileEvent
;
339 friend class DeviceStorageRequest
;
341 static mozilla::StaticAutoPtr
<nsTArray
<nsString
>> sVolumeNameCache
;
343 #ifdef MOZ_WIDGET_GONK
344 nsString mLastStatus
;
345 nsString mLastStorageStatus
;
346 void DispatchStatusChangeEvent(nsAString
& aStatus
);
347 void DispatchStorageStatusChangeEvent(nsAString
& aStorageStatus
);
350 // nsIDOMDeviceStorage.type
352 DEVICE_STORAGE_TYPE_DEFAULT
= 0,
353 DEVICE_STORAGE_TYPE_SHARED
,
354 DEVICE_STORAGE_TYPE_EXTERNAL
357 nsRefPtr
<DeviceStorageFileSystem
> mFileSystem
;