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 107052 089c534af34efe339050b122824cbefd8784a149
parent 107051 7653a9cc00aecfa3aaccada5772f53cf56ae4ba3
child 107053 7c8b9e22567e4254bd5bf3bc962f52a9ef955d03
push id23466
push userdougt@mozilla.com
push dateFri, 14 Sep 2012 16:33:32 +0000
treeherdermozilla-central@6eec6da1392c [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;
       }
     }
   }
 }
@@ -783,17 +787,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);
@@ -1197,17 +1201,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);
@@ -1633,17 +1637,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>
+