Bug 1525582 - Resolve OrientationPendingPromise after change event fires r=baku
authorMarcos Cáceres <mcaceres@mozilla.com>
Wed, 13 Feb 2019 18:08:24 +0000
changeset 459832 60cf625574a9
parent 459821 8231f78228bc
child 459833 a42ee9783546
push id35576
push userbtara@mozilla.com
push dateTue, 19 Feb 2019 09:46:27 +0000
treeherdermozilla-central@dd4aa59c6a12 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1525582
milestone67.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 1525582 - Resolve OrientationPendingPromise after change event fires r=baku spec was changed so promise resolves after the event fires. Differential Revision: https://phabricator.services.mozilla.com/D19612
dom/base/ScreenOrientation.cpp
dom/base/ScreenOrientation.h
--- a/dom/base/ScreenOrientation.cpp
+++ b/dom/base/ScreenOrientation.cpp
@@ -517,43 +517,46 @@ void ScreenOrientation::Notify(const hal
                                      mVisibleListener, /* useCapture = */ true);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "AddSystemEventListener failed");
     return;
   }
 
   if (mType != doc->CurrentOrientationType()) {
     doc->SetCurrentOrientation(mType, mAngle);
 
-    Promise* pendingPromise = doc->GetOrientationPendingPromise();
-    if (pendingPromise) {
-      pendingPromise->MaybeResolveWithUndefined();
-      doc->SetOrientationPendingPromise(nullptr);
-    }
-
-    nsCOMPtr<nsIRunnable> runnable =
-        NewRunnableMethod("dom::ScreenOrientation::DispatchChangeEvent", this,
-                          &ScreenOrientation::DispatchChangeEvent);
+    nsCOMPtr<nsIRunnable> runnable = DispatchChangeEventAndResolvePromise();
     rv = NS_DispatchToMainThread(runnable);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
   }
 }
 
 void ScreenOrientation::UpdateActiveOrientationLock(
     hal::ScreenOrientation aOrientation) {
   if (aOrientation == hal::eScreenOrientation_None) {
     hal::UnlockScreenOrientation();
   } else {
     DebugOnly<bool> ok = hal::LockScreenOrientation(aOrientation);
     NS_WARNING_ASSERTION(ok, "hal::LockScreenOrientation failed");
   }
 }
 
-void ScreenOrientation::DispatchChangeEvent() {
-  DebugOnly<nsresult> rv = DispatchTrustedEvent(NS_LITERAL_STRING("change"));
-  NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "DispatchTrustedEvent failed");
+nsCOMPtr<nsIRunnable> ScreenOrientation::DispatchChangeEventAndResolvePromise() {
+  RefPtr<Document> doc = GetResponsibleDocument();
+  RefPtr<ScreenOrientation> self = this;
+  return NS_NewRunnableFunction("dom::ScreenOrientation::DispatchChangeEvent", [self, doc]() {
+    DebugOnly<nsresult> rv = self->DispatchTrustedEvent(NS_LITERAL_STRING("change"));
+    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "DispatchTrustedEvent failed");
+    if (doc) {
+      Promise* pendingPromise = doc->GetOrientationPendingPromise();
+      if (pendingPromise) {
+        pendingPromise->MaybeResolveWithUndefined();
+        doc->SetOrientationPendingPromise(nullptr);
+      }
+    }
+  });
 }
 
 JSObject* ScreenOrientation::WrapObject(JSContext* aCx,
                                         JS::Handle<JSObject*> aGivenProto) {
   return ScreenOrientation_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 bool ScreenOrientation::ShouldResistFingerprinting() const {
@@ -596,25 +599,17 @@ ScreenOrientation::VisibleEventListener:
   target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this,
                                     true);
 
   if (doc->CurrentOrientationType() !=
       orientation->DeviceType(CallerType::System)) {
     doc->SetCurrentOrientation(orientation->DeviceType(CallerType::System),
                                orientation->DeviceAngle(CallerType::System));
 
-    Promise* pendingPromise = doc->GetOrientationPendingPromise();
-    if (pendingPromise) {
-      pendingPromise->MaybeResolveWithUndefined();
-      doc->SetOrientationPendingPromise(nullptr);
-    }
-
-    nsCOMPtr<nsIRunnable> runnable =
-        NewRunnableMethod("dom::ScreenOrientation::DispatchChangeEvent",
-                          orientation, &ScreenOrientation::DispatchChangeEvent);
+    nsCOMPtr<nsIRunnable> runnable = orientation->DispatchChangeEventAndResolvePromise();
     rv = NS_DispatchToMainThread(runnable);
     if (NS_WARN_IF(rv.Failed())) {
       return rv.StealNSResult();
     }
   }
 
   return NS_OK;
 }
--- a/dom/base/ScreenOrientation.h
+++ b/dom/base/ScreenOrientation.h
@@ -81,17 +81,17 @@ class ScreenOrientation final
 
   // This method performs the same function as |Lock| except it takes
   // a hal::ScreenOrientation argument instead of an OrientationType.
   // This method exists in order to share implementation with nsScreen that
   // uses ScreenOrientation.
   already_AddRefed<Promise> LockInternal(hal::ScreenOrientation aOrientation,
                                          ErrorResult& aRv);
 
-  void DispatchChangeEvent();
+  nsCOMPtr<nsIRunnable> DispatchChangeEventAndResolvePromise();
 
   bool ShouldResistFingerprinting() const;
 
   LockPermission GetLockOrientationPermission(bool aCheckSandbox) const;
 
   // Gets the responsible document as defined in the spec.
   Document* GetResponsibleDocument() const;