Bug 949325 - C++ wrapper to support DataStore API on the worker (part 2-6, a proxy to run HasDataStoreSupport() on the main thread). r=khuey
authorGene Lian <clian@mozilla.com>
Wed, 12 Mar 2014 17:03:05 +0800
changeset 181365 8d6bb2cbb91e1ae0438abbc381b82bc7dafaa4ed
parent 181364 6c5b716e26c8b5324a12d25d1e1bb277f3292fe5
child 181366 2bbfeafe352cd73226044341d78eefc92be99ac5
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerskhuey
bugs949325
milestone32.0a1
Bug 949325 - C++ wrapper to support DataStore API on the worker (part 2-6, a proxy to run HasDataStoreSupport() on the main thread). r=khuey
dom/base/Navigator.cpp
dom/base/Navigator.h
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -89,16 +89,19 @@
 #include "mozilla/dom/NavigatorBinding.h"
 #include "mozilla/dom/Promise.h"
 
 #include "nsIUploadChannel2.h"
 #include "nsFormData.h"
 #include "nsIPrivateBrowsingChannel.h"
 #include "nsIDocShell.h"
 
+#include "WorkerPrivate.h"
+#include "WorkerRunnable.h"
+
 namespace mozilla {
 namespace dom {
 
 static bool sDoNotTrackEnabled = false;
 static bool sVibratorEnabled   = false;
 static uint32_t sMaxVibrateMS  = 0;
 static uint32_t sMaxVibrateListLen = 0;
 
@@ -2294,48 +2297,101 @@ Navigator::HasInputMethodSupport(JSConte
   }
 
   return CheckPermission(win, "input") ||
          CheckPermission(win, "input-manage");
 }
 
 /* static */
 bool
-Navigator::HasDataStoreSupport(JSContext* cx, JSObject* aGlobal)
+Navigator::HasDataStoreSupport(nsIPrincipal* aPrincipal)
 {
-  JS::Rooted<JSObject*> global(cx, aGlobal);
+  workers::AssertIsOnMainThread();
 
   // First of all, the general pref has to be turned on.
   bool enabled = false;
   Preferences::GetBool("dom.datastore.enabled", &enabled);
   if (!enabled) {
     return false;
   }
 
   // Just for testing, we can enable DataStore for any kind of app.
   if (Preferences::GetBool("dom.testing.datastore_enabled_for_hosted_apps", false)) {
     return true;
   }
 
+  uint16_t status;
+  if (NS_FAILED(aPrincipal->GetAppStatus(&status))) {
+    return false;
+  }
+
+  // Only support DataStore API for certified apps for now.
+  return status == nsIPrincipal::APP_STATUS_CERTIFIED;
+}
+
+// A WorkerMainThreadRunnable to synchronously dispatch the call of
+// HasDataStoreSupport() from the worker thread to the main thread.
+class HasDataStoreSupportRunnable MOZ_FINAL
+  : public workers::WorkerMainThreadRunnable
+{
+public:
+  bool mResult;
+
+  HasDataStoreSupportRunnable(workers::WorkerPrivate* aWorkerPrivate)
+    : workers::WorkerMainThreadRunnable(aWorkerPrivate)
+    , mResult(false)
+  {
+    MOZ_ASSERT(aWorkerPrivate);
+    aWorkerPrivate->AssertIsOnWorkerThread();
+  }
+
+protected:
+  virtual bool
+  MainThreadRun() MOZ_OVERRIDE
+  {
+    workers::AssertIsOnMainThread();
+
+    mResult = Navigator::HasDataStoreSupport(mWorkerPrivate->GetPrincipal());
+
+    return true;
+  }
+};
+
+/* static */
+bool
+Navigator::HasDataStoreSupport(JSContext* aCx, JSObject* aGlobal)
+{
+  // If the caller is on the worker thread, dispatch this to the main thread.
+  if (!NS_IsMainThread()) {
+    workers::WorkerPrivate* workerPrivate =
+      workers::GetWorkerPrivateFromContext(aCx);
+    workerPrivate->AssertIsOnWorkerThread();
+
+    nsRefPtr<HasDataStoreSupportRunnable> runnable =
+      new HasDataStoreSupportRunnable(workerPrivate);
+    runnable->Dispatch(aCx);
+
+    return runnable->mResult;
+  }
+
+  workers::AssertIsOnMainThread();
+
+  JS::Rooted<JSObject*> global(aCx, aGlobal);
+
   nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(global);
   if (!win) {
     return false;
   }
 
   nsIDocument* doc = win->GetExtantDoc();
   if (!doc || !doc->NodePrincipal()) {
     return false;
   }
 
-  uint16_t status;
-  if (NS_FAILED(doc->NodePrincipal()->GetAppStatus(&status))) {
-    return false;
-  }
-
-  return status == nsIPrincipal::APP_STATUS_CERTIFIED;
+  return HasDataStoreSupport(doc->NodePrincipal());
 }
 
 /* static */
 bool
 Navigator::HasDownloadsSupport(JSContext* aCx, JSObject* aGlobal)
 {
   nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
 
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -22,16 +22,17 @@
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsPIDOMWindow;
 class nsIDOMMozMobileMessageManager;
 class nsIDOMNavigatorSystemMessages;
 class nsDOMCameraManager;
 class nsDOMDeviceStorage;
 class nsIDOMBlob;
+class nsIPrincipal;
 
 namespace mozilla {
 namespace dom {
 class Geolocation;
 class systemMessageCallback;
 class MediaStreamConstraints;
 class WakeLock;
 class ArrayBufferViewOrBlobOrStringOrFormData;
@@ -299,16 +300,18 @@ public:
                                   JSObject* /* unused */);
 #endif // MOZ_MEDIA_NAVIGATOR
 
   static bool HasPushNotificationsSupport(JSContext* /* unused */,
                                           JSObject* aGlobal);
 
   static bool HasInputMethodSupport(JSContext* /* unused */, JSObject* aGlobal);
 
+  static bool HasDataStoreSupport(nsIPrincipal* aPrincipal);
+
   static bool HasDataStoreSupport(JSContext* cx, JSObject* aGlobal);
 
   static bool HasDownloadsSupport(JSContext* aCx, JSObject* aGlobal);
 
   static bool HasPermissionSettingsSupport(JSContext* aCx, JSObject* aGlobal);
 
   nsPIDOMWindow* GetParentObject() const
   {