Bug 1286429 - Fire fake devicechange event in Camera IPC thread for mochitest; r=jib

MozReview-Commit-ID: 9sDLnMGh3xL

--HG--
extra : rebase_source : 026891d00450b9bfd792708ab3d5d2e730f431f9
This commit is contained in:
Munro Mengjue Chiang 2016-08-09 16:37:04 +08:00
parent 4eb2d3e90d
commit 730a993044
7 changed files with 69 additions and 1 deletions

View File

@ -1709,6 +1709,7 @@ MediaManager::MediaManager()
mPrefs.mNoiseOn = false;
mPrefs.mExtendedFilter = true;
mPrefs.mDelayAgnostic = true;
mPrefs.mFakeDeviceChangeEventOn = false;
#ifdef MOZ_WEBRTC
mPrefs.mAec = webrtc::kEcUnchanged;
mPrefs.mAgc = webrtc::kAgcUnchanged;
@ -1807,6 +1808,7 @@ MediaManager::Get() {
prefs->AddObserver("media.getusermedia.noise_enabled", sSingleton, false);
prefs->AddObserver("media.getusermedia.noise", sSingleton, false);
prefs->AddObserver("media.getusermedia.playout_delay", sSingleton, false);
prefs->AddObserver("media.ondevicechange.fakeDeviceChangeEvent.enabled", sSingleton, false);
#endif
}
@ -1999,9 +2001,12 @@ bool MediaManager::IsPrivateBrowsing(nsPIDOMWindowInner* window)
int MediaManager::AddDeviceChangeCallback(DeviceChangeCallback* aCallback)
{
MediaManager::PostTask(NewTaskFrom([]() {
bool fakeDeviceChangeEventOn = mPrefs.mFakeDeviceChangeEventOn;
MediaManager::PostTask(NewTaskFrom([fakeDeviceChangeEventOn]() {
RefPtr<MediaManager> manager = MediaManager_GetInstance();
manager->GetBackend(0)->AddDeviceChangeCallback(manager);
if (fakeDeviceChangeEventOn)
manager->GetBackend(0)->SetFakeDeviceChangeEvents();
}));
return DeviceChangeCallback::AddDeviceChangeCallback(aCallback);
@ -2875,6 +2880,7 @@ MediaManager::GetPrefs(nsIPrefBranch *aBranch, const char *aData)
GetPref(aBranch, "media.getusermedia.playout_delay", aData, &mPrefs.mPlayoutDelay);
GetPrefBool(aBranch, "media.getusermedia.aec_extended_filter", aData, &mPrefs.mExtendedFilter);
GetPrefBool(aBranch, "media.getusermedia.aec_aec_delay_agnostic", aData, &mPrefs.mDelayAgnostic);
GetPrefBool(aBranch, "media.ondevicechange.fakeDeviceChangeEvent.enabled", aData, &mPrefs.mFakeDeviceChangeEventOn);
#endif
GetPrefBool(aBranch, "media.navigator.audio.full_duplex", aData, &mPrefs.mFullDuplex);
}
@ -2911,6 +2917,7 @@ MediaManager::Shutdown()
prefs->RemoveObserver("media.getusermedia.noise_enabled", this);
prefs->RemoveObserver("media.getusermedia.noise", this);
prefs->RemoveObserver("media.getusermedia.playout_delay", this);
prefs->RemoveObserver("media.ondevicechange.fakeDeviceChangeEvent.enabled", this);
#endif
prefs->RemoveObserver("media.navigator.audio.full_duplex", this);
}

View File

@ -25,6 +25,9 @@ mozilla::LazyLogModule gCamerasChildLog("CamerasChild");
#define LOG(args) MOZ_LOG(gCamerasChildLog, mozilla::LogLevel::Debug, args)
#define LOG_ENABLED() MOZ_LOG_TEST(gCamerasChildLog, mozilla::LogLevel::Debug)
#define FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS 5000
#define FAKE_ONDEVICECHANGE_EVENT_REPEAT_COUNT 30
namespace mozilla {
namespace camera {
@ -39,6 +42,34 @@ CamerasSingleton::~CamerasSingleton() {
LOG(("~CamerasSingleton: %p", this));
}
class FakeOnDeviceChangeEventRunnable : public Runnable
{
public:
explicit FakeOnDeviceChangeEventRunnable(uint8_t counter)
: mCounter(counter) {}
NS_IMETHOD Run() override
{
OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
CamerasChild* child = CamerasSingleton::Child();
if (child) {
child->OnDeviceChange();
if (mCounter++ < FAKE_ONDEVICECHANGE_EVENT_REPEAT_COUNT) {
RefPtr<FakeOnDeviceChangeEventRunnable> evt = new FakeOnDeviceChangeEventRunnable(mCounter);
CamerasSingleton::Thread()->DelayedDispatch(evt.forget(),
FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS);
}
}
return NS_OK;
}
private:
uint8_t mCounter;
};
class InitializeIPCThread : public Runnable
{
public:
@ -592,6 +623,19 @@ CamerasChild::RecvDeviceChange()
return true;
}
int
CamerasChild::SetFakeDeviceChangeEvents()
{
CamerasSingleton::Mutex().AssertCurrentThreadOwns();
// To simulate the devicechange event in mochitest,
// we fire a fake devicechange event in Camera IPC thread periodically
RefPtr<FakeOnDeviceChangeEventRunnable> evt = new FakeOnDeviceChangeEventRunnable(0);
CamerasSingleton::Thread()->Dispatch(evt.forget(), NS_DISPATCH_NORMAL);
return 0;
}
bool
CamerasChild::RecvFrameSizeChange(const int& capEngine,
const int& capId,

View File

@ -160,6 +160,7 @@ public:
const int& w, const int& h) override;
virtual bool RecvDeviceChange() override;
int SetFakeDeviceChangeEvents();
// these are response messages to our outgoing requests
virtual bool RecvReplyNumberOfCaptureDevices(const int&) override;

View File

@ -76,6 +76,8 @@ public:
virtual void Shutdown() = 0;
virtual void SetFakeDeviceChangeEvents() {}
protected:
virtual ~MediaEngine() {}
};
@ -101,6 +103,7 @@ public:
, mFullDuplex(false)
, mExtendedFilter(false)
, mDelayAgnostic(false)
, mFakeDeviceChangeEventOn(false)
{}
int32_t mWidth;
@ -118,6 +121,7 @@ public:
bool mFullDuplex;
bool mExtendedFilter;
bool mDelayAgnostic;
bool mFakeDeviceChangeEventOn;
// mWidth and/or mHeight may be zero (=adaptive default), so use functions.

View File

@ -132,6 +132,13 @@ MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
this);
}
void
MediaEngineWebRTC::SetFakeDeviceChangeEvents()
{
camera::GetChildAndCall(
&camera::CamerasChild::SetFakeDeviceChangeEvents);
}
void
MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
nsTArray<RefPtr<MediaEngineVideoSource> >* aVSources)

View File

@ -571,6 +571,8 @@ class MediaEngineWebRTC : public MediaEngine
public:
explicit MediaEngineWebRTC(MediaEnginePrefs& aPrefs);
virtual void SetFakeDeviceChangeEvents() override;
// Clients should ensure to clean-up sources video/audio sources
// before invoking Shutdown on this class.
void Shutdown() override;

View File

@ -4797,6 +4797,9 @@ pref("dom.imagecapture.enabled", false);
// W3C MediaDevices devicechange event
pref("media.ondevicechange.enabled", false);
// W3C MediaDevices devicechange fake event
pref("media.ondevicechange.fakeDeviceChangeEvent.enabled", false);
// W3C touch-action css property (related to touch and pointer events)
// Note that we turn this on even on platforms/configurations where touch
// events are not supported (e.g. OS X, or Windows with e10s disabled). For