Bug 1330350 - add holding mechanism to fix faulty device counter; r=jib draft
authorMunro Mengjue Chiang <mchiang@mozilla.com>
Fri, 27 Jan 2017 00:08:06 +0800
changeset 467035 128dbc5001a1211faa79cf3821c4a9ed00f01622
parent 466816 d92fd6b6d6bfc5b566222ae2957e55772d60151a
child 543611 80b9415c227db0ad40e3101de6490dccdb935778
push id43095
push userbmo:mchiang@mozilla.com
push dateFri, 27 Jan 2017 02:50:37 +0000
reviewersjib
bugs1330350
milestone54.0a1
Bug 1330350 - add holding mechanism to fix faulty device counter; r=jib MozReview-Commit-ID: CIUucjaglK1
dom/media/MediaDevices.cpp
dom/media/MediaDevices.h
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -10,19 +10,42 @@
 #include "mozilla/MediaManager.h"
 #include "MediaTrackConstraints.h"
 #include "nsIEventTarget.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIPermissionManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsQueryObject.h"
 
+#define DEVICECHANGE_HOLD_TIME_IN_MS 1000
+
 namespace mozilla {
 namespace dom {
 
+class FuzzTimerCallBack final : public nsITimerCallback
+{
+  ~FuzzTimerCallBack() {}
+
+public:
+  explicit FuzzTimerCallBack(MediaDevices* aMediaDevices) : mMediaDevices(aMediaDevices) {}
+
+  NS_DECL_ISUPPORTS
+
+  NS_IMETHOD Notify(nsITimer* aTimer) final
+  {
+    mMediaDevices->DispatchTrustedEvent(NS_LITERAL_STRING("devicechange"));
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<MediaDevices> mMediaDevices;
+};
+
+NS_IMPL_ISUPPORTS(FuzzTimerCallBack, nsITimerCallback)
+
 class MediaDevices::GumResolver : public nsIDOMGetUserMediaSuccessCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   explicit GumResolver(Promise* aPromise) : mPromise(aPromise) {}
 
   NS_IMETHOD
@@ -187,25 +210,39 @@ NS_INTERFACE_MAP_BEGIN(MediaDevices)
   NS_INTERFACE_MAP_ENTRY(MediaDevices)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 void
 MediaDevices::OnDeviceChange()
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsresult rv = CheckInnerWindowCorrectness();
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
+    MOZ_ASSERT(false);
     return;
+  }
 
   if (!(MediaManager::Get()->IsActivelyCapturingOrHasAPermission(GetOwner()->WindowID()) ||
     Preferences::GetBool("media.navigator.permission.disabled", false))) {
     return;
   }
 
-  DispatchTrustedEvent(NS_LITERAL_STRING("devicechange"));
+  if (!mFuzzTimer)
+  {
+    mFuzzTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
+  }
+
+  if (!mFuzzTimer) {
+    MOZ_ASSERT(false);
+    return;
+  }
+
+  mFuzzTimer->Cancel();
+  RefPtr<FuzzTimerCallBack> cb = new FuzzTimerCallBack(this);
+  mFuzzTimer->InitWithCallback(cb, DEVICECHANGE_HOLD_TIME_IN_MS, nsITimer::TYPE_ONE_SHOT);
 }
 
 mozilla::dom::EventHandlerNonNull*
 MediaDevices::GetOndevicechange()
 {
   if (NS_IsMainThread()) {
     return GetEventHandler(nsGkAtoms::ondevicechange, EmptyString());
   }
--- a/dom/media/MediaDevices.h
+++ b/dom/media/MediaDevices.h
@@ -62,16 +62,17 @@ public:
                                 ErrorResult& aRv) override;
 
 private:
   class GumResolver;
   class EnumDevResolver;
   class GumRejecter;
 
   virtual ~MediaDevices();
+  nsCOMPtr<nsITimer> mFuzzTimer;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
                               MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
 
 } // namespace dom
 } // namespace mozilla