Bug 957439 - Do not assert at Pause or Resume on unsupported input stream. r=roc, r=jsmith
authorShelly Lin <slin@mozilla.com>
Mon, 27 Jan 2014 10:33:00 +0800
changeset 181386 4680e4f0354b44bb710aefcb8b7541c494a29ff3
parent 181385 a331400db013bd863d738236fe054fc62aec415f
child 181387 dd2ff26244c927eac5e1d3cd8e0f003bf546fb8a
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, jsmith
bugs957439
milestone29.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 957439 - Do not assert at Pause or Resume on unsupported input stream. r=roc, r=jsmith
content/media/MediaRecorder.cpp
content/media/test/mochitest.ini
content/media/test/test_mediarecorder_unsupported_src.html
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -225,28 +225,30 @@ public:
   void Stop()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     CleanupStreams();
     nsContentUtils::UnregisterShutdownObserver(this);
   }
 
-  void Pause()
+  nsresult Pause()
   {
-    MOZ_ASSERT(NS_IsMainThread() && mTrackUnionStream);
+    NS_ENSURE_TRUE(NS_IsMainThread() && mTrackUnionStream, NS_ERROR_FAILURE);
+    mTrackUnionStream->ChangeExplicitBlockerCount(-1);
 
-    mTrackUnionStream->ChangeExplicitBlockerCount(-1);
+    return NS_OK;
   }
 
-  void Resume()
+  nsresult Resume()
   {
-    MOZ_ASSERT(NS_IsMainThread() && mTrackUnionStream);
+    NS_ENSURE_TRUE(NS_IsMainThread() && mTrackUnionStream, NS_ERROR_FAILURE);
+    mTrackUnionStream->ChangeExplicitBlockerCount(1);
 
-    mTrackUnionStream->ChangeExplicitBlockerCount(1);
+    return NS_OK;
   }
 
   already_AddRefed<nsIDOMBlob> GetEncodedData()
   {
     nsString mimeType;
     mRecorder->GetMimeType(mimeType);
 
     return mEncodedBufferCache->ExtractBlob(mimeType);
@@ -494,36 +496,42 @@ MediaRecorder::Stop(ErrorResult& aResult
 void
 MediaRecorder::Pause(ErrorResult& aResult)
 {
   if (mState != RecordingState::Recording) {
     aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
-  mState = RecordingState::Paused;
-
   MOZ_ASSERT(mSession != nullptr);
   if (mSession) {
-    mSession->Pause();
+    nsresult rv = mSession->Pause();
+    if (NS_FAILED(rv)) {
+      NotifyError(rv);
+      return;
+    }
     mState = RecordingState::Paused;
   }
 }
 
 void
 MediaRecorder::Resume(ErrorResult& aResult)
 {
   if (mState != RecordingState::Paused) {
     aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   MOZ_ASSERT(mSession != nullptr);
   if (mSession) {
-    mSession->Resume();
+    nsresult rv = mSession->Resume();
+    if (NS_FAILED(rv)) {
+      NotifyError(rv);
+      return;
+    }
     mState = RecordingState::Recording;
   }
 }
 
 void
 MediaRecorder::RequestData(ErrorResult& aResult)
 {
   if (mState != RecordingState::Recording) {
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -251,16 +251,17 @@ support-files =
 [test_mozHasAudio.html]
 [test_source_media.html]
 [test_autoplay_contentEditable.html]
 [test_decoder_disable.html]
 [test_mediarecorder_record_no_timeslice.html]
 [test_mediarecorder_reload_crash.html]
 [test_mediarecorder_record_immediate_stop.html]
 [test_mediarecorder_record_session.html]
+[test_mediarecorder_unsupported_src.html]
 [test_playback.html]
 [test_seekLies.html]
 [test_media_sniffer.html]
 [test_streams_srcObject.html]
 [test_reset_src.html]
 [test_streams_autoplay.html]
 [test_streams_element_capture.html]
 [test_streams_element_capture_reset.html]
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_mediarecorder_unsupported_src.html
@@ -0,0 +1,90 @@
+<html>
+<head>
+  <title>Bug 957439 - Media Recording - Assertion fail at Pause if unsupported input stream.</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957439">Mozilla Bug 957439</a>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+function startTest() {
+  navigator.mozGetUserMedia({audio: false, video: true, fake: true},
+    function(stream) {
+
+      // Expected callback sequence should be:
+      // 1. onerror (from start)
+      // 2. onerror (from pause)
+      // 3. ondataavailable
+      // 4. onstop
+      var callbackStep = 0;
+      var mediaRecorder = new MediaRecorder(stream);
+
+      is(mediaRecorder.stream, stream, 'Stream should be provided on creation');
+
+      mediaRecorder.onerror = function (e) {
+        callbackStep++;
+        ok(callbackStep < 3, 'onerror callback fired as expected.');
+        is(e.name, 'GenericError', 'Error name should be GenericError.');
+        is(mediaRecorder.mimeType, '', 'mimetype should be empty');
+        is(mediaRecorder.state, 'recording', 'state is recording');
+        info('onerror callback fired');
+      }
+
+      mediaRecorder.onwarning = function () {
+        ok(false, 'Unexpected onwarning callback fired.');
+      };
+
+      mediaRecorder.ondataavailable = function (evt) {
+        callbackStep++;
+        info('ondataavailable callback fired');
+        is(callbackStep, 3, 'should fired ondataavailable callback');
+        is(evt.data.size, 0, 'data size should be zero');
+        ok(evt instanceof BlobEvent,
+           'Events fired from ondataavailable should be BlobEvent');
+        is(evt.data.type, '', 'encoder start fail, blob miemType should be empty');
+      };
+
+      mediaRecorder.onstop = function() {
+        callbackStep++;
+        info('onstop callback fired');
+        is(mediaRecorder.state, 'inactive', 'state should be inactive');
+        is(callbackStep, 4, 'should fired onstop callback');
+        SimpleTest.finish();
+      };
+
+      try {
+        mediaRecorder.start();
+      } catch(e) {
+        ok(false, 'Should not get exception in start call.');
+      }
+
+      try {
+        mediaRecorder.pause();
+      } catch(e) {
+        ok(false, 'Should not get exception in pause call.');
+      }
+    },
+    function(err) {
+      ok(false, 'Unexpected error fired with: ' + err);
+      SimpleTest.finish();
+    }
+  );
+}
+
+SimpleTest.waitForExplicitFinish();
+
+// In order to generate an "unsupported stream", pref off video encoding to
+// make the platform support audio encoding only.
+SpecialPowers.pushPrefEnv(
+  {
+    "set": [
+      ["media.encoder.webm.enabled", false]
+    ]
+  }, startTest);
+
+</script>
+</head>
+</html>