Bug 794619 - Remote the blobs returned from enumerate. r=bent
authorDoug Turner <dougt@dougt.org>
Thu, 04 Oct 2012 13:40:45 -0700
changeset 115585 d7c8896af07ae086a779aa880eb1770616996a82
parent 115584 e619280855e5f91edb92d7c2e7f52ea215dd7679
child 115586 ce3664d2eec863815f0264c41a762a5ad6f48568
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersbent
bugs794619
milestone18.0a1
Bug 794619 - Remote the blobs returned from enumerate. r=bent
dom/devicestorage/DeviceStorageRequestChild.cpp
dom/devicestorage/DeviceStorageRequestChild.h
dom/devicestorage/nsDeviceStorage.cpp
dom/devicestorage/nsDeviceStorage.h
dom/ipc/ContentChild.cpp
--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ b/dom/devicestorage/DeviceStorageRequestChild.cpp
@@ -9,35 +9,42 @@
 #include "nsDOMFile.h"
 #include "mozilla/dom/ipc/Blob.h"
 
 namespace mozilla {
 namespace dom {
 namespace devicestorage {
 
 DeviceStorageRequestChild::DeviceStorageRequestChild()
+  : mCallback(nullptr)
 {
   MOZ_COUNT_CTOR(DeviceStorageRequestChild);
 }
 
 DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest,
                                                      DeviceStorageFile* aFile)
   : mRequest(aRequest)
   , mFile(aFile)
+  , mCallback(nullptr)
 {
   MOZ_COUNT_CTOR(DeviceStorageRequestChild);
 }
 
 DeviceStorageRequestChild::~DeviceStorageRequestChild() {
   MOZ_COUNT_DTOR(DeviceStorageRequestChild);
 }
 
 bool
 DeviceStorageRequestChild::Recv__delete__(const DeviceStorageResponseValue& aValue)
 {
+  if (mCallback) {
+    mCallback->RequestComplete();
+    mCallback = nullptr;
+  }
+
   switch (aValue.type()) {
 
     case DeviceStorageResponseValue::TErrorResponse:
     {
       ErrorResponse r = aValue;
       mRequest->FireError(r.error());
       break;
     }
@@ -85,25 +92,30 @@ DeviceStorageRequestChild::Recv__delete_
         }
 
         nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(r.paths()[i].type(), f);
         dsf->SetPath(r.paths()[i].name());
         cursor->mFiles.AppendElement(dsf);
       }
 
       nsCOMPtr<ContinueCursorEvent> event = new ContinueCursorEvent(cursor);
-      NS_DispatchToMainThread(event);
+      event->Continue();
       break;
     }
 
     default:
     {
       NS_RUNTIMEABORT("not reached");
       break;
     }
   }
   return true;
 }
 
+void
+DeviceStorageRequestChild::SetCallback(DeviceStorageRequestChildCallback *aCallback)
+{
+  mCallback = aCallback;
+}
 
 } // namespace devicestorage
 } // namespace dom
 } // namespace mozilla
--- a/dom/devicestorage/DeviceStorageRequestChild.h
+++ b/dom/devicestorage/DeviceStorageRequestChild.h
@@ -3,32 +3,44 @@
  * 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 mozilla_dom_devicestorage_DeviceStorageRequestChild_h
 #define mozilla_dom_devicestorage_DeviceStorageRequestChild_h
 
 #include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
 #include "DOMRequest.h"
-#include "nsDeviceStorage.h"
+
+class DeviceStorageFile;
+
 namespace mozilla {
 namespace dom {
 namespace devicestorage {
 
+class DeviceStorageRequestChildCallback
+{
+  public:
+    virtual void RequestComplete() = 0;
+};
+
 class DeviceStorageRequestChild : public PDeviceStorageRequestChild
 {
 public:
   DeviceStorageRequestChild();
   DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile);
   ~DeviceStorageRequestChild();
 
+  void SetCallback(class DeviceStorageRequestChildCallback *aCallback);
+
   virtual bool Recv__delete__(const DeviceStorageResponseValue& value);
 
 private:
   nsRefPtr<DOMRequest> mRequest;
   nsRefPtr<DeviceStorageFile> mFile;
+
+  DeviceStorageRequestChildCallback* mCallback;
 };
 
 } // namespace devicestorage
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -746,22 +746,22 @@ jsval InterfaceToJsval(nsPIDOMWindow* aW
   return someJsVal;
 }
 
 jsval nsIFileToJsval(nsPIDOMWindow* aWindow, DeviceStorageFile* aFile)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aWindow, "Null Window");
 
-  if (aFile->mEditable) {
-    // TODO - needs janv's file handle support.
+  if (!aFile) {
     return JSVAL_NULL;
   }
 
-  if (aFile == nullptr) {
+  if (aFile->mEditable) {
+    // TODO - needs janv's file handle support.
     return JSVAL_NULL;
   }
 
   nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(aFile->mFile, aFile->mPath);
   return InterfaceToJsval(aWindow, blob, &NS_GET_IID(nsIDOMBlob));
  }
 
 
@@ -907,44 +907,88 @@ ContinueCursorEvent::ContinueCursorEvent
   mRequest.swap(aRequest);
 }
 
 ContinueCursorEvent::ContinueCursorEvent(DOMRequest* aRequest)
   : mRequest(aRequest)
 {
 }
 
-ContinueCursorEvent::~ContinueCursorEvent() {}
-
-NS_IMETHODIMP
-ContinueCursorEvent::Run() {
+already_AddRefed<DeviceStorageFile>
+ContinueCursorEvent::GetNextFile()
+{
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
-  jsval val = JSVAL_NULL;
-
   nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
   nsString cursorStorageType;
   cursor->GetStorageType(cursorStorageType);
 
   DeviceStorageTypeChecker* typeChecker = DeviceStorageTypeChecker::CreateOrGet();
   if (!typeChecker) {
-    return NS_ERROR_FAILURE;
+    return nullptr;
   }
 
   while (cursor->mFiles.Length() > 0) {
     nsRefPtr<DeviceStorageFile> file = cursor->mFiles[0];
     cursor->mFiles.RemoveElementAt(0);
     if (!typeChecker->Check(cursorStorageType, file->mFile)) {
       continue;
     }
-    val = nsIFileToJsval(cursor->GetOwner(), file);
-    cursor->mOkToCallContinue = true;
-    break;
+    return file.forget();
+  }
+
+  return nullptr;
+}
+
+ContinueCursorEvent::~ContinueCursorEvent() {}
+
+void
+ContinueCursorEvent::Continue()
+{
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    NS_DispatchToMainThread(this);
+    return;
+  }
+
+  nsRefPtr<DeviceStorageFile> file = GetNextFile();
+
+  if (!file) {
+    // done with enumeration.
+    NS_DispatchToMainThread(this);
+    return;
   }
 
+  nsString fullpath;
+  nsresult rv = file->mFile->GetPath(fullpath);
+  if (NS_FAILED(rv)) {
+    NS_ASSERTION(false, "GetPath failed to return a valid path");
+    return;
+  }
+
+  nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
+  nsString cursorStorageType;
+  cursor->GetStorageType(cursorStorageType);
+
+  DeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, file);
+  child->SetCallback(cursor);
+  DeviceStorageGetParams params(cursorStorageType, file->mPath, fullpath);
+  ContentChild::GetSingleton()->SendPDeviceStorageRequestConstructor(child, params);
+  mRequest = nullptr;
+}
+
+NS_IMETHODIMP
+ContinueCursorEvent::Run()
+{
+  nsRefPtr<DeviceStorageFile> file = GetNextFile();
+
+  nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
+  jsval val = nsIFileToJsval(cursor->GetOwner(), file);
+
+  cursor->mOkToCallContinue = true;
+
   mRequest->FireSuccess(val);
   mRequest = nullptr;
   return NS_OK;
 }
 
 class InitCursorEvent : public nsRunnable
 {
 public:
@@ -1127,16 +1171,23 @@ nsDOMDeviceStorageCursor::Recv__delete__
 }
 
 void
 nsDOMDeviceStorageCursor::IPDLRelease()
 {
   Release();
 }
 
+void
+nsDOMDeviceStorageCursor::RequestComplete()
+{
+  NS_ASSERTION(!mOkToCallContinue, "mOkToCallContinue must be false");  
+  mOkToCallContinue = true;
+}
+
 class PostStatResultEvent : public nsRunnable
 {
 public:
   PostStatResultEvent(nsRefPtr<DOMRequest>& aRequest, uint64_t aFreeBytes, uint64_t aTotalBytes)
     : mFreeBytes(aFreeBytes)
     , mTotalBytes(aTotalBytes)
     {
       mRequest.swap(aRequest);
--- a/dom/devicestorage/nsDeviceStorage.h
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -25,27 +25,30 @@ class nsPIDOMWindow;
 #include "nsIDOMEventListener.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIObserver.h"
 #include "nsIStringBundle.h"
 #include "mozilla/Mutex.h"
 #include "prtime.h"
 #include "DeviceStorage.h"
 
+#include "DeviceStorageRequestChild.h"
 
 #define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST         "File location doesn't exists"
 #define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE         "File location is not enumerable"
 #define POST_ERROR_EVENT_PERMISSION_DENIED           "Permission Denied"
 #define POST_ERROR_EVENT_ILLEGAL_FILE_NAME           "Illegal file name"
 #define POST_ERROR_EVENT_ILLEGAL_TYPE                "Illegal content type"
 #define POST_ERROR_EVENT_UNKNOWN                     "Unknown"
 #define POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED "Non-string type unsupported"
 #define POST_ERROR_EVENT_NOT_IMPLEMENTED             "Not implemented"
 
+using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::dom::devicestorage;
 
 class DeviceStorageTypeChecker MOZ_FINAL
 {
 public:
   static DeviceStorageTypeChecker* CreateOrGet();
 
   DeviceStorageTypeChecker();
   ~DeviceStorageTypeChecker();
@@ -92,32 +95,36 @@ public:
 
   static void DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar, const nsAString& aStorageType);
 
 private:
   void NormalizeFilePath();
   void AppendRelativePath();
 };
 
-class ContinueCursorEvent MOZ_FINAL: public nsRunnable
+class ContinueCursorEvent MOZ_FINAL : public nsRunnable
 {
 public:
   ContinueCursorEvent(nsRefPtr<DOMRequest>& aRequest);
   ContinueCursorEvent(DOMRequest* aRequest);
   ~ContinueCursorEvent();
+  void Continue();
+
   NS_IMETHOD Run();
 private:
+  already_AddRefed<DeviceStorageFile> GetNextFile();
   nsRefPtr<DOMRequest> mRequest;
 };
 
 class nsDOMDeviceStorageCursor MOZ_FINAL
   : public nsIDOMDeviceStorageCursor
   , public DOMRequest
   , public nsIContentPermissionRequest
   , public PCOMContentPermissionRequestChild
+  , public DeviceStorageRequestChildCallback
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSICONTENTPERMISSIONREQUEST
   NS_DECL_NSIDOMDEVICESTORAGECURSOR
 
   nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
                            nsIPrincipal* aPrincipal,
@@ -129,16 +136,18 @@ public:
   bool mOkToCallContinue;
   PRTime mSince;
 
   virtual bool Recv__delete__(const bool& allow);
   virtual void IPDLRelease();
 
   void GetStorageType(nsAString & aType);
 
+  void RequestComplete();
+
 private:
   ~nsDOMDeviceStorageCursor();
 
   nsRefPtr<DeviceStorageFile> mFile;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 class nsDOMDeviceStorageStat MOZ_FINAL
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -97,16 +97,17 @@
 #include "nsDOMFile.h"
 #include "nsIRemoteBlob.h"
 #include "ProcessUtils.h"
 #include "StructuredCloneUtils.h"
 #include "URIUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsIPrincipal.h"
+#include "nsDeviceStorage.h"
 
 using namespace base;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::sms;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::hal_sandbox;