Bug 1362912. P2 - fix the callers. r=gerald
authorJW Wang <jwwang@mozilla.com>
Tue, 09 May 2017 23:31:32 +0800
changeset 357417 86297713a790e3e84826f5a752600d98644f718b
parent 357416 54b325c535a7193276cec80870ba10b99b764bd9
child 357418 29f227f273dfcab6743986fcc05d93c4c2af5510
push id42357
push userjwwang@mozilla.com
push dateWed, 10 May 2017 08:37:41 +0000
treeherderautoland@86297713a790 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1362912
milestone55.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 1362912. P2 - fix the callers. r=gerald MozReview-Commit-ID: LdYcIWAFDUn
dom/media/MediaDecoderReaderWrapper.cpp
dom/media/MediaDecoderReaderWrapper.h
dom/media/MediaFormatReader.cpp
dom/media/gmp/GMPServiceParent.cpp
dom/media/gtest/TestMozPromise.cpp
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/omx/OmxDataDecoder.cpp
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -49,18 +49,21 @@ MediaDecoderReaderWrapper::RequestAudioD
   MOZ_ASSERT(!mShutdown);
 
   int64_t startTime = StartTime().ToMicroseconds();
   return InvokeAsync(mReader->OwnerThread(), mReader.get(),
                      __func__, &MediaDecoderReader::RequestAudioData)
     ->Then(mOwnerThread, __func__,
            [startTime] (AudioData* aAudio) {
              aAudio->AdjustForStartTime(startTime);
+             return AudioDataPromise::CreateAndResolve(aAudio, __func__);
            },
-           [] (const MediaResult& aError) {});
+           [] (const MediaResult& aError) {
+             return AudioDataPromise::CreateAndReject(aError, __func__);
+           });
 }
 
 RefPtr<MediaDecoderReaderWrapper::VideoDataPromise>
 MediaDecoderReaderWrapper::RequestVideoData(bool aSkipToNextKeyframe,
                                             media::TimeUnit aTimeThreshold)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
@@ -72,18 +75,21 @@ MediaDecoderReaderWrapper::RequestVideoD
   int64_t startTime = StartTime().ToMicroseconds();
   return InvokeAsync(
     mReader->OwnerThread(), mReader.get(), __func__,
     &MediaDecoderReader::RequestVideoData,
     aSkipToNextKeyframe, aTimeThreshold)
   ->Then(mOwnerThread, __func__,
          [startTime] (VideoData* aVideo) {
            aVideo->AdjustForStartTime(startTime);
+           return VideoDataPromise::CreateAndResolve(aVideo, __func__);
          },
-         [] (const MediaResult& aError) {});
+         [] (const MediaResult& aError) {
+           return VideoDataPromise::CreateAndReject(aError, __func__);
+         });
 }
 
 RefPtr<MediaDecoderReader::SeekPromise>
 MediaDecoderReaderWrapper::Seek(const SeekTarget& aTarget)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   SeekTarget adjustedTarget = aTarget;
   adjustedTarget.SetTime(adjustedTarget.GetTime() + StartTime());
@@ -126,27 +132,35 @@ RefPtr<ShutdownPromise>
 MediaDecoderReaderWrapper::Shutdown()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   mShutdown = true;
   return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
                      &MediaDecoderReader::Shutdown);
 }
 
-void
+RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
 MediaDecoderReaderWrapper::OnMetadataRead(MetadataHolder* aMetadata)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   if (mShutdown) {
-    return;
+    return MetadataPromise::CreateAndReject(
+      NS_ERROR_DOM_MEDIA_ABORT_ERR, __func__);
   }
 
   if (mStartTime.isNothing()) {
     mStartTime.emplace(aMetadata->mInfo.mStartTime);
   }
+  return MetadataPromise::CreateAndResolve(aMetadata, __func__);
+}
+
+RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
+MediaDecoderReaderWrapper::OnMetadataNotRead(const MediaResult& aError)
+{
+  return MetadataPromise::CreateAndReject(aError, __func__);
 }
 
 void
 MediaDecoderReaderWrapper::SetVideoBlankDecode(bool aIsBlankDecode)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   nsCOMPtr<nsIRunnable> r =
     NewRunnableMethod<bool>(mReader, &MediaDecoderReader::SetVideoNullDecode,
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -85,18 +85,18 @@ public:
   }
 
   void SetCDMProxy(CDMProxy* aProxy) { mReader->SetCDMProxy(aProxy); }
 
   void SetVideoBlankDecode(bool aIsBlankDecode);
 
 private:
   ~MediaDecoderReaderWrapper();
-  void OnMetadataRead(MetadataHolder* aMetadata);
-  void OnMetadataNotRead() {}
+  RefPtr<MetadataPromise> OnMetadataRead(MetadataHolder* aMetadata);
+  RefPtr<MetadataPromise> OnMetadataNotRead(const MediaResult& aError);
 
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaDecoderReader> mReader;
 
   bool mShutdown = false;
   Maybe<media::TimeUnit> mStartTime;
 };
 
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -565,18 +565,19 @@ public:
     return mDecoder->SupportDecoderRecycling();
   }
   RefPtr<ShutdownPromise> Shutdown() override
   {
     RefPtr<MediaDataDecoder> decoder = mDecoder.forget();
     RefPtr<Token> token = mToken.forget();
     return decoder->Shutdown()->Then(
       AbstractThread::GetCurrent(), __func__,
-      [token]() {},
-      [token]() { MOZ_RELEASE_ASSERT(false, "Can't reach here"); });
+      [token]() {
+        return ShutdownPromise::CreateAndResolve(true, __func__);
+      });
   }
 
 private:
   RefPtr<MediaDataDecoder> mDecoder;
   RefPtr<Token> mToken;
 };
 
 void
@@ -884,30 +885,42 @@ public:
 
   RefPtr<SeekPromise> Seek(const TimeUnit& aTime) override
   {
     RefPtr<Wrapper> self = this;
     return InvokeAsync(
              mTaskQueue, __func__,
              [self, aTime]() { return self->mTrackDemuxer->Seek(aTime); })
       ->Then(mTaskQueue, __func__,
-             [self]() { self->UpdateRandomAccessPoint(); },
-             [self]() { self->UpdateRandomAccessPoint(); });
+             [self](const TimeUnit& aTime) {
+               self->UpdateRandomAccessPoint();
+               return SeekPromise::CreateAndResolve(aTime, __func__);
+             },
+             [self](const MediaResult& aError) {
+               self->UpdateRandomAccessPoint();
+               return SeekPromise::CreateAndReject(aError, __func__);
+             });
   }
 
   RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples) override
   {
     RefPtr<Wrapper> self = this;
     return InvokeAsync(mTaskQueue, __func__,
                        [self, aNumSamples]() {
                          return self->mTrackDemuxer->GetSamples(aNumSamples);
                        })
       ->Then(mTaskQueue, __func__,
-             [self]() { self->UpdateRandomAccessPoint(); },
-             [self]() { self->UpdateRandomAccessPoint(); });
+             [self](RefPtr<SamplesHolder> aSamples) {
+               self->UpdateRandomAccessPoint();
+               return SamplesPromise::CreateAndResolve(aSamples.forget(), __func__);
+             },
+             [self](const MediaResult& aError) {
+               self->UpdateRandomAccessPoint();
+               return SamplesPromise::CreateAndReject(aError, __func__);
+             });
   }
 
   bool GetSamplesMayBlock() const override
   {
     return mGetSamplesMayBlock;
   }
 
   void Reset() override
@@ -933,18 +946,24 @@ public:
     RefPtr<Wrapper> self = this;
     return InvokeAsync(
              mTaskQueue, __func__,
              [self, aTimeThreshold]()  {
                return self->mTrackDemuxer->SkipToNextRandomAccessPoint(
                  aTimeThreshold);
              })
       ->Then(mTaskQueue, __func__,
-             [self]() { self->UpdateRandomAccessPoint(); },
-             [self]() { self->UpdateRandomAccessPoint(); });
+             [self](uint32_t aVal) {
+               self->UpdateRandomAccessPoint();
+               return SkipAccessPointPromise::CreateAndResolve(aVal, __func__);
+             },
+             [self](const SkipFailureHolder& aError) {
+               self->UpdateRandomAccessPoint();
+               return SkipAccessPointPromise::CreateAndReject(aError, __func__);
+             });
   }
 
   TimeIntervals GetBuffered() override
   {
     MutexAutoLock lock(mMutex);
     return mBuffered;
   }
 
@@ -992,30 +1011,33 @@ private:
     MutexAutoLock lock(mMutex);
     mBuffered = mTrackDemuxer->GetBuffered();
   }
 };
 
 RefPtr<MediaDataDemuxer::InitPromise>
 MediaFormatReader::DemuxerProxy::Init()
 {
+  using InitPromise = MediaDataDemuxer::InitPromise;
+
   RefPtr<Data> data = mData;
   RefPtr<AutoTaskQueue> taskQueue = mTaskQueue;
   return InvokeAsync(mTaskQueue, __func__,
                      [data, taskQueue]() {
                        if (!data->mDemuxer) {
-                         return MediaDataDemuxer::InitPromise::CreateAndReject(
+                         return InitPromise::CreateAndReject(
                            NS_ERROR_DOM_MEDIA_CANCELED, __func__);
                        }
                        return data->mDemuxer->Init();
                      })
     ->Then(taskQueue, __func__,
            [data, taskQueue]() {
              if (!data->mDemuxer) { // Was shutdown.
-               return;
+               return InitPromise::CreateAndReject(
+                   NS_ERROR_DOM_MEDIA_CANCELED, __func__);
              }
              data->mNumAudioTrack =
                data->mDemuxer->GetNumberTracks(TrackInfo::kAudioTrack);
              if (data->mNumAudioTrack) {
                RefPtr<MediaTrackDemuxer> d =
                  data->mDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
                if (d) {
                  RefPtr<Wrapper> wrapper =
@@ -1038,18 +1060,21 @@ MediaFormatReader::DemuxerProxy::Init()
              }
              data->mCrypto = data->mDemuxer->GetCrypto();
              data->mSeekable = data->mDemuxer->IsSeekable();
              data->mSeekableOnlyInBufferedRange =
                data->mDemuxer->IsSeekableOnlyInBufferedRanges();
              data->mShouldComputeStartTime =
                data->mDemuxer->ShouldComputeStartTime();
              data->mInitDone = true;
+             return InitPromise::CreateAndResolve(NS_OK, __func__);
            },
-           []() {});
+           [](const MediaResult& aError) {
+             return InitPromise::CreateAndReject(aError, __func__);
+           });
 }
 
 RefPtr<MediaFormatReader::NotifyDataArrivedPromise>
 MediaFormatReader::DemuxerProxy::NotifyDataArrived()
 {
   RefPtr<Data> data = mData;
   return InvokeAsync(mTaskQueue, __func__, [data]() {
     if (!data->mDemuxer) {
@@ -1609,26 +1634,30 @@ MediaFormatReader::OnDemuxFailed(TrackTy
       NotifyError(aTrack, aError);
       break;
   }
 }
 
 void
 MediaFormatReader::DoDemuxVideo()
 {
+  using SamplesPromise = MediaTrackDemuxer::SamplesPromise;
+
   auto p = mVideo.mTrackDemuxer->GetSamples(1);
 
   if (mVideo.mFirstDemuxedSampleTime.isNothing()) {
     RefPtr<MediaFormatReader> self = this;
     p = p->Then(OwnerThread(), __func__,
                 [self] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
                   self->OnFirstDemuxCompleted(TrackInfo::kVideoTrack, aSamples);
+                  return SamplesPromise::CreateAndResolve(aSamples.forget(), __func__);
                 },
                 [self] (const MediaResult& aError) {
                   self->OnFirstDemuxFailed(TrackInfo::kVideoTrack, aError);
+                  return SamplesPromise::CreateAndReject(aError, __func__);
                 });
   }
 
   p->Then(OwnerThread(), __func__, this,
           &MediaFormatReader::OnVideoDemuxCompleted,
           &MediaFormatReader::OnVideoDemuxFailed)
    ->Track(mVideo.mDemuxRequest);
 }
@@ -1682,26 +1711,30 @@ MediaFormatReader::RequestAudioData()
   ScheduleUpdate(TrackInfo::kAudioTrack);
 
   return p;
 }
 
 void
 MediaFormatReader::DoDemuxAudio()
 {
+  using SamplesPromise = MediaTrackDemuxer::SamplesPromise;
+
   auto p = mAudio.mTrackDemuxer->GetSamples(1);
 
   if (mAudio.mFirstDemuxedSampleTime.isNothing()) {
     RefPtr<MediaFormatReader> self = this;
     p = p->Then(OwnerThread(), __func__,
                 [self] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
                   self->OnFirstDemuxCompleted(TrackInfo::kAudioTrack, aSamples);
+                  return SamplesPromise::CreateAndResolve(aSamples.forget(), __func__);
                 },
                 [self] (const MediaResult& aError) {
                   self->OnFirstDemuxFailed(TrackInfo::kAudioTrack, aError);
+                  return SamplesPromise::CreateAndReject(aError, __func__);
                 });
   }
 
   p->Then(OwnerThread(), __func__, this,
           &MediaFormatReader::OnAudioDemuxCompleted,
           &MediaFormatReader::OnAudioDemuxFailed)
    ->Track(mAudio.mDemuxRequest);
 }
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -643,25 +643,27 @@ GeckoMediaPluginServiceParent::AsyncAddP
   nsString dir(aDirectory);
   RefPtr<GeckoMediaPluginServiceParent> self = this;
   return InvokeAsync(
            thread, this, __func__,
            &GeckoMediaPluginServiceParent::AddOnGMPThread, dir)
     ->Then(
       mMainThread,
       __func__,
-      [dir, self]() -> void {
+      [dir, self](bool aVal) {
         LOGD(("GeckoMediaPluginServiceParent::AsyncAddPluginDirectory %s succeeded",
               NS_ConvertUTF16toUTF8(dir).get()));
         MOZ_ASSERT(NS_IsMainThread());
         self->UpdateContentProcessGMPCapabilities();
+        return GenericPromise::CreateAndResolve(aVal, __func__);
       },
-      [dir]() -> void {
+      [dir](nsresult aResult) {
         LOGD(("GeckoMediaPluginServiceParent::AsyncAddPluginDirectory %s failed",
               NS_ConvertUTF16toUTF8(dir).get()));
+        return GenericPromise::CreateAndReject(aResult, __func__);
       });
 }
 
 NS_IMETHODIMP
 GeckoMediaPluginServiceParent::AddPluginDirectory(const nsAString& aDirectory)
 {
   MOZ_ASSERT(NS_IsMainThread());
   RefPtr<GenericPromise> p = AsyncAddPluginDirectory(aDirectory);
@@ -869,25 +871,27 @@ GeckoMediaPluginServiceParent::AddOnGMPT
   RefPtr<GMPParent> gmp = CreateGMPParent(mMainThread);
   if (!gmp) {
     NS_WARNING("Can't Create GMPParent");
     return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
   RefPtr<GeckoMediaPluginServiceParent> self(this);
   return gmp->Init(this, directory)->Then(thread, __func__,
-    [gmp, self, dir]() -> void {
+    [gmp, self, dir](bool aVal) {
       LOGD(("%s::%s: %s Succeeded", __CLASS__, __FUNCTION__, dir.get()));
       {
         MutexAutoLock lock(self->mMutex);
         self->mPlugins.AppendElement(gmp);
       }
+      return GenericPromise::CreateAndResolve(aVal, __func__);
     },
-    [dir]() -> void {
+    [dir](nsresult aResult) {
       LOGD(("%s::%s: %s Failed", __CLASS__, __FUNCTION__, dir.get()));
+      return GenericPromise::CreateAndReject(aResult, __func__);
     });
 }
 
 void
 GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
                                                  const bool aDeleteFromDisk,
                                                  const bool aCanDefer)
 {
--- a/dom/media/gtest/TestMozPromise.cpp
+++ b/dom/media/gtest/TestMozPromise.cpp
@@ -83,17 +83,17 @@ template<typename FunctionType>
 void
 RunOnTaskQueue(TaskQueue* aQueue, FunctionType aFun)
 {
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(aFun);
   aQueue->Dispatch(r.forget());
 }
 
 // std::function can't come soon enough. :-(
-#define DO_FAIL []()->void { EXPECT_TRUE(false); }
+#define DO_FAIL []() { EXPECT_TRUE(false); return TestPromise::CreateAndReject(0, __func__); }
 
 TEST(MozPromise, BasicResolve)
 {
   AutoTaskQueue atq;
   RefPtr<TaskQueue> queue = atq.Queue();
   RunOnTaskQueue(queue, [queue] () -> void {
     TestPromise::CreateAndResolve(42, __func__)->Then(queue, __func__,
       [queue] (int aResolveValue) -> void { EXPECT_EQ(aResolveValue, 42); queue->BeginShutdown(); },
@@ -180,17 +180,21 @@ TEST(MozPromise, CompletionPromises)
   bool invokedPass = false;
   AutoTaskQueue atq;
   RefPtr<TaskQueue> queue = atq.Queue();
   RunOnTaskQueue(queue, [queue, &invokedPass] () -> void {
     TestPromise::CreateAndResolve(40, __func__)
     ->Then(queue, __func__,
       [] (int aVal) -> RefPtr<TestPromise> { return TestPromise::CreateAndResolve(aVal + 10, __func__); },
       DO_FAIL)
-    ->Then(queue, __func__, [&invokedPass] () -> void { invokedPass = true; }, DO_FAIL)
+    ->Then(queue, __func__,
+           [&invokedPass] (int aVal) {
+             invokedPass = true;
+             return TestPromise::CreateAndResolve(aVal, __func__);
+           }, DO_FAIL)
     ->Then(queue, __func__,
       [queue] (int aVal) -> RefPtr<TestPromise> {
         RefPtr<TestPromise::Private> p = new TestPromise::Private(__func__);
         nsCOMPtr<nsIRunnable> resolver = new DelayedResolveOrReject(queue, p, RRValue::MakeResolve(aVal - 8), 10);
         queue->Dispatch(resolver.forget());
         return RefPtr<TestPromise>(p);
       },
       DO_FAIL)
@@ -217,17 +221,17 @@ TEST(MozPromise, PromiseAllResolve)
     TestPromise::All(queue, promises)->Then(queue, __func__,
       [queue] (const nsTArray<int>& aResolveValues) -> void {
         EXPECT_EQ(aResolveValues.Length(), 3UL);
         EXPECT_EQ(aResolveValues[0], 22);
         EXPECT_EQ(aResolveValues[1], 32);
         EXPECT_EQ(aResolveValues[2], 42);
         queue->BeginShutdown();
       },
-      DO_FAIL
+      []() { EXPECT_TRUE(false); }
     );
   });
 }
 
 TEST(MozPromise, PromiseAllReject)
 {
   AutoTaskQueue atq;
   RefPtr<TaskQueue> queue = atq.Queue();
@@ -236,17 +240,17 @@ TEST(MozPromise, PromiseAllReject)
     nsTArray<RefPtr<TestPromise>> promises;
     promises.AppendElement(TestPromise::CreateAndResolve(22, __func__));
     promises.AppendElement(TestPromise::CreateAndReject(32.0, __func__));
     promises.AppendElement(TestPromise::CreateAndResolve(42, __func__));
    // Ensure that more than one rejection doesn't cause a crash (bug #1207312)
     promises.AppendElement(TestPromise::CreateAndReject(52.0, __func__));
 
     TestPromise::All(queue, promises)->Then(queue, __func__,
-      DO_FAIL,
+      []() { EXPECT_TRUE(false); },
       [queue] (float aRejectValue) -> void {
         EXPECT_EQ(aRejectValue, 32.0);
         queue->BeginShutdown();
       }
     );
   });
 }
 
@@ -260,18 +264,21 @@ TEST(MozPromise, Chaining)
 
   RunOnTaskQueue(queue, [queue, &holder] () {
     auto p = TestPromise::CreateAndResolve(42, __func__);
     const size_t kIterations = 100;
     for (size_t i = 0; i < kIterations; ++i) {
       p = p->Then(queue, __func__,
         [] (int aVal) {
           EXPECT_EQ(aVal, 42);
+          return TestPromise::CreateAndResolve(aVal, __func__);
         },
-        [] () {}
+        [] (double aVal) {
+          return TestPromise::CreateAndReject(aVal, __func__);
+        }
       );
 
       if (i == kIterations / 2) {
         p->Then(queue, __func__,
           [queue, &holder] () {
             holder.Disconnect();
             queue->BeginShutdown();
           },
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -168,18 +168,22 @@ public:
     mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     mThroughputLimiter.Flush();
     for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
       nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
       holder->DisconnectIfExists();
       iter.Remove();
     }
     RefPtr<SamplesWaitingForKey> k = mSamplesWaitingForKey;
-    return mDecoder->Flush()->Then(mTaskQueue, __func__,
-                                   [k]() { k->Flush(); });
+    return mDecoder->Flush()->Then(
+      mTaskQueue, __func__,
+      [k]() {
+        k->Flush();
+        return FlushPromise::CreateAndResolve(true, __func__);
+      });
   }
 
   RefPtr<DecodePromise> Drain() override
   {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     MOZ_ASSERT(!mIsShutdown);
     MOZ_ASSERT(mDecodePromise.IsEmpty() && !mDecodeRequest.Exists(),
                "Must wait for decoding to complete");
--- a/dom/media/platforms/omx/OmxDataDecoder.cpp
+++ b/dom/media/platforms/omx/OmxDataDecoder.cpp
@@ -236,18 +236,19 @@ OmxDataDecoder::DoAsyncShutdown()
   // Flush to all ports, so all buffers can be returned from component.
   RefPtr<OmxDataDecoder> self = this;
   mOmxLayer->SendCommand(OMX_CommandFlush, OMX_ALL, nullptr)
     ->Then(mOmxTaskQueue, __func__,
            [self] () -> RefPtr<OmxCommandPromise> {
              LOGL("DoAsyncShutdown: flush complete");
              return self->mOmxLayer->SendCommand(OMX_CommandStateSet, OMX_StateIdle, nullptr);
            },
-           [self] () {
+           [self] (const OmxCommandFailureHolder& aError) {
              self->mOmxLayer->Shutdown();
+             return OmxCommandPromise::CreateAndReject(aError, __func__);
            })
     ->Then(mOmxTaskQueue, __func__,
            [self] () -> RefPtr<OmxCommandPromise> {
              RefPtr<OmxCommandPromise> p =
                self->mOmxLayer->SendCommand(OMX_CommandStateSet, OMX_StateLoaded, nullptr);
 
              // According to spec 3.1.1.2.2.1:
              // OMX_StateLoaded needs to be sent before releasing buffers.
@@ -258,18 +259,19 @@ OmxDataDecoder::DoAsyncShutdown()
              // in layer, it needs to wait before the layer returns the
              // buffers.
              LOGL("DoAsyncShutdown: releasing buffers...");
              self->ReleaseBuffers(OMX_DirInput);
              self->ReleaseBuffers(OMX_DirOutput);
 
              return p;
            },
-           [self] () {
+           [self] (const OmxCommandFailureHolder& aError) {
              self->mOmxLayer->Shutdown();
+             return OmxCommandPromise::CreateAndReject(aError, __func__);
            })
     ->Then(mOmxTaskQueue, __func__,
            [self] () {
              LOGL("DoAsyncShutdown: OMX_StateLoaded, it is safe to shutdown omx");
              self->mOmxLayer->Shutdown();
              self->mWatchManager.Shutdown();
              self->mOmxLayer = nullptr;
              self->mMediaDataHelper = nullptr;
@@ -781,18 +783,19 @@ OmxDataDecoder::PortSettingsChanged()
                // Allocate new port buffers.
                nsresult rv = self->AllocateBuffers(def.eDir);
                if (NS_FAILED(rv)) {
                  self->NotifyError(OMX_ErrorUndefined, __func__);
                }
 
                return p;
              },
-             [self] () {
+             [self] (const OmxCommandFailureHolder& aError) {
                self->NotifyError(OMX_ErrorUndefined, __func__);
+               return OmxCommandPromise::CreateAndReject(aError, __func__);
              })
       ->Then(mOmxTaskQueue, __func__,
              [self] () {
                LOGL("PortSettingsChanged: port settings changed complete");
                // finish port setting changed.
                self->mPortSettingsChanged = -1;
                self->FillAndEmptyBuffers();
              },