Bug 787299 - Device Storage - Filter out mimetypes during calculation of disk usages. r=bent
authorDoug Turner <dougt@dougt.org>
Wed, 05 Sep 2012 14:30:36 -0700
changeset 107046 6996c091767dec473f59633765fa876005120755
parent 107045 b53f4627bcc8b5d74ffb50e3d28df7a32efb3987
child 107047 b040fefd038ea8b4e27a0343c7dd42d8f1eeffba
push id23464
push userdougt@mozilla.com
push dateFri, 14 Sep 2012 05:37:34 +0000
treeherdermozilla-central@e5af3d785252 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs787299
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 787299 - Device Storage - Filter out mimetypes during calculation of disk usages. r=bent
dom/devicestorage/DeviceStorageRequestParent.cpp
dom/devicestorage/nsDeviceStorage.cpp
dom/devicestorage/nsDeviceStorage.h
dom/devicestorage/test/Makefile.in
dom/devicestorage/test/test_diskSpace.html
--- a/dom/devicestorage/DeviceStorageRequestParent.cpp
+++ b/dom/devicestorage/DeviceStorageRequestParent.cpp
@@ -308,17 +308,17 @@ DeviceStorageRequestParent::StatFileEven
 
 nsresult
 DeviceStorageRequestParent::StatFileEvent::CancelableRun()
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
 
   nsCOMPtr<nsIRunnable> r;
   uint64_t diskUsage = 0;
-  DeviceStorageFile::DirectoryDiskUsage(mFile->mFile, &diskUsage);
+  DeviceStorageFile::DirectoryDiskUsage(mFile->mFile, &diskUsage, mFile->mStorageType);
   int64_t freeSpace = 0;
   nsresult rv = mFile->mFile->GetDiskSpaceAvailable(&freeSpace);
   if (NS_FAILED(rv)) {
     freeSpace = 0;
   }
   
   r = new PostStatResultEvent(mParent, freeSpace, diskUsage);
   NS_DispatchToMainThread(r);
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -146,47 +146,45 @@ DeviceStorageFile::IsSafePath()
         PL_strcmp(token, "..") == 0 ) {
       return false;
     }
   }
   return true;
 }
 
 bool
-DeviceStorageFile::IsType(nsAString& aType)
+DeviceStorageFile::IsType(nsIFile* aFile, const nsAString& aStorageType)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
   // String bundles are cached by the bundle service.
   nsCOMPtr<nsIStringBundleService> stringService = mozilla::services::GetStringBundleService();
   if (!stringService) {
     return false;
   }
 
   nsCOMPtr<nsIStringBundle> filterBundle;
   if (NS_FAILED(stringService->CreateBundle(DEVICESTORAGE_PROPERTIES,
 					    getter_AddRefs(filterBundle)))) {
     return false;
   }
 
   nsString path;
-  mFile->GetPath(path);
+  aFile->GetPath(path);
 
   int32_t dotIdx = path.RFindChar(PRUnichar('.'));
   if (dotIdx == kNotFound) {
     return false;
   }
 
   nsAutoString extensionMatch;
   extensionMatch.AssignASCII("*");
   extensionMatch.Append(Substring(path, dotIdx));
   extensionMatch.AppendASCII(";");
 
   nsString extensionListStr;
-  if (NS_FAILED(filterBundle->GetStringFromName(aType.BeginReading(),
+  if (NS_FAILED(filterBundle->GetStringFromName(aStorageType.BeginReading(),
 						getter_Copies(extensionListStr)))) {
     return false;
   }
 
   return FindInReadable(extensionMatch, extensionListStr);
 }
 
 void
@@ -400,17 +398,17 @@ DeviceStorageFile::collectFilesInternal(
       nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, f);
       dsf->SetPath(newPath);
       aFiles.AppendElement(dsf);
     }
   }
 }
 
 void
-DeviceStorageFile::DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar)
+DeviceStorageFile::DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar, const nsAString& aStorageType)
 {
   if (!aFile) {
     return;
   }
 
   nsresult rv;
   nsCOMPtr<nsISimpleEnumerator> e;
   rv = aFile->GetDirectoryEntries(getter_AddRefs(e));
@@ -436,22 +434,28 @@ DeviceStorageFile::DirectoryDiskUsage(ns
       continue;
     }
 
     bool isLink;
     rv = f->IsSymlink(&isLink);
     if (NS_FAILED(rv)) {
       continue;
     }
+
     if (isLink) {
       // for now, lets just totally ignore symlinks.
       NS_WARNING("DirectoryDiskUsage ignores symlinks");
     } else if (isDir) {
-      DirectoryDiskUsage(f, aSoFar);
+      DirectoryDiskUsage(f, aSoFar, aStorageType);
     } else if (isFile) {
+
+      if (!DeviceStorageFile::IsType(f, aStorageType)) {
+	continue;
+      }
+
       int64_t size;
       rv = f->GetFileSize(&size);
       if (NS_SUCCEEDED(rv)) {
 	*aSoFar += size;
       }
     }
   }
 }
@@ -774,17 +778,17 @@ ContinueCursorEvent::Run() {
 
   nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
   nsString cursorStorageType;
   cursor->GetStorageType(cursorStorageType);
 
   while (cursor->mFiles.Length() > 0) {
     nsRefPtr<DeviceStorageFile> file = cursor->mFiles[0];
     cursor->mFiles.RemoveElementAt(0);
-    if (!file->IsType(cursorStorageType)) {
+    if (!DeviceStorageFile::IsType(file->mFile, cursorStorageType)) {
       continue;
     }
     val = nsIFileToJsval(cursor->GetOwner(), file);
     cursor->mOkToCallContinue = true;
     break;
   }
 
   mRequest->FireSuccess(val);
@@ -1188,17 +1192,17 @@ public:
 
   ~StatFileEvent() {}
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
     nsCOMPtr<nsIRunnable> r;
     uint64_t diskUsage = 0;
-    DeviceStorageFile::DirectoryDiskUsage(mFile->mFile, &diskUsage);
+    DeviceStorageFile::DirectoryDiskUsage(mFile->mFile, &diskUsage, mFile->mStorageType);
     int64_t freeSpace = 0;
     nsresult rv = mFile->mFile->GetDiskSpaceAvailable(&freeSpace);
     if (NS_FAILED(rv)) {
       freeSpace = 0;
     }
 
     r = new PostStatResultEvent(mRequest, freeSpace, diskUsage);
     NS_DispatchToMainThread(r);
@@ -1624,17 +1628,17 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob 
   }
 
   nsRefPtr<DOMRequest> request = new DOMRequest(win);
   NS_ADDREF(*_retval = request);
 
   nsCOMPtr<nsIRunnable> r;
 
   nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, mRootDirectory, aPath);
-  if (!dsf->IsType(mStorageType) || !IsMimeTypeCorrectForStorageType(mStorageType, aBlob)) {
+  if (!DeviceStorageFile::IsType(dsf->mFile, mStorageType) || !IsMimeTypeCorrectForStorageType(mStorageType, aBlob)) {
     r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_TYPE, dsf);
   }
   else if (!dsf->IsSafePath()) {
     r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
   }
   else {
     r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE,
 				 win, mPrincipal, dsf, request, aBlob);
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -54,25 +54,25 @@ public:
   void SetPath(const nsAString& aPath);
   void SetEditable(bool aEditable);
 
   NS_DECL_ISUPPORTS
 
   // 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 IsType(nsAString& aType);
 
   nsresult Remove();
   nsresult Write(nsIInputStream* aInputStream);
   nsresult Write(InfallibleTArray<uint8_t>& bits);
   void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince = 0);
   void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince, nsAString& aRootPath);
 
-  static void DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar);
+  static bool IsType(nsIFile* aFile, const nsAString& aStorageType);
+  static void DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar, const nsAString& aStorageType);
 
 private:
   void NormalizeFilePath();
   void AppendRelativePath();
 };
 
 class ContinueCursorEvent MOZ_FINAL: public nsRunnable
 {
--- a/dom/devicestorage/test/Makefile.in
+++ b/dom/devicestorage/test/Makefile.in
@@ -15,16 +15,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES	= \
 		test_sanity.html \
 		test_addCorrectType.html \
 		test_basic.html \
 		test_enumerate.html \
 		test_enumerateMultipleContinue.html \
 		test_overwrite.html \
+		test_diskSpace.html \
 		test_dotdot.html \
 		test_enumerateOptions.html \
 		test_lastModificationFilter.html \
 		test_stat.html \
 		test_watch.html \
 		test_watchOther.html \
 		devicestorage_common.js \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/dom/devicestorage/test/test_diskSpace.html
@@ -0,0 +1,101 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html> <!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.js"></script>
+
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+devicestorage_setup();
+
+
+var freeBytes = -1;
+var stats = 0;
+
+function stat(s, file_list_length) {
+  if (freeBytes == -1) {
+    freeBytes = s.target.result.freeBytes;
+  }
+
+  ok(freeBytes == s.target.result.freeBytes, "Free bytes should be the same");
+  ok(file_list_length * 1024 == s.target.result.totalBytes, "space taken up by files should match")
+
+  stats = stats + 1;
+
+  if (stats == 2) {
+    devicestorage_cleanup();
+  }
+}
+
+function addSuccess(e) {
+  added = added - 1;
+
+  if (added == 0) {
+    request = pictures.stat();
+    request.onsuccess = function(s) {stat(s, picture_files.length)};
+
+    request = videos.stat();
+    request.onsuccess = function(s) {stat(s, video_files.length)};
+
+    request = music.stat();
+    request.onsuccess = function(s) {stat(s, music_files.length)};
+  }
+}
+
+function addError(e) {
+  ok(false, "addError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+ok(true, "hi");
+
+var pictures = navigator.getDeviceStorage("pictures");
+var picture_files = [ "a.png", "b.png", "c.png", "d.png", "e.png" ];
+
+var videos = navigator.getDeviceStorage("videos");
+var video_files = [ "a.ogv", "b.ogv" ];
+
+var music = navigator.getDeviceStorage("music");
+var music_files = [ "a.mp3", "b.mp3", "c.mp3" ];
+
+var added = picture_files.length + video_files.length + music_files.length;
+
+for (var i=0; i < picture_files.length; i++) {
+ request = pictures.addNamed(createRandomBlob('image/png'), picture_files[i]);
+ request.onsuccess = addSuccess;
+ request.onerror = addError;
+}
+
+for (var i=0; i < video_files.length; i++) {
+ request = videos.addNamed(createRandomBlob('video/ogv'), video_files[i]);
+ request.onsuccess = addSuccess;
+ request.onerror = addError;
+}
+
+for (var i=0; i < music_files.length; i++) {
+ request = music.addNamed(createRandomBlob('audio/mp3'), music_files[i]);
+ request.onsuccess = addSuccess;
+ request.onerror = addError;
+}
+
+</script>
+</pre>
+</body>
+</html>
+