Bug 938809 - Run seek/tune calls off the main thread, r=pzhang,khuey
authorMichael Wu <mwu@mozilla.com>
Mon, 14 Jul 2014 17:56:10 -0400
changeset 196813 4cc9e0c5dd67f9dabae2b45c3c212a985624e0b4
parent 196812 ef03bec1272a480fe6a86afa9b23be4e865ea867
child 196814 b3ee1c63e4432a5d7327e380144170387456f5f4
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerspzhang, khuey
bugs938809
milestone34.0a1
Bug 938809 - Run seek/tune calls off the main thread, r=pzhang,khuey
dom/fmradio/FMRadioService.cpp
dom/fmradio/FMRadioService.h
--- a/dom/fmradio/FMRadioService.cpp
+++ b/dom/fmradio/FMRadioService.cpp
@@ -130,16 +130,23 @@ public:
     FMRadioSettings info;
     info.upperLimit() = mUpperLimit;
     info.lowerLimit() = mLowerLimit;
     info.spaceType() = mSpaceType;
     info.preEmphasis() = mPreemphasis;
 
     EnableFMRadio(info);
 
+    FMRadioService* fmRadioService = FMRadioService::Singleton();
+    if (!fmRadioService->mTuneThread) {
+      // SeekRunnable and SetFrequencyRunnable run on this thread.
+      // These call ioctls that can stall the main thread, so we run them here.
+      NS_NewNamedThread("FM Tuning", getter_AddRefs(fmRadioService->mTuneThread));
+    }
+
     return NS_OK;
   }
 
 private:
   uint32_t mUpperLimit;
   uint32_t mLowerLimit;
   uint32_t mSpaceType;
   uint32_t mPreemphasis;
@@ -209,20 +216,25 @@ NS_IMPL_ISUPPORTS(ReadAirplaneModeSettin
 
 class DisableRunnable MOZ_FINAL : public nsRunnable
 {
 public:
   DisableRunnable() { }
 
   NS_IMETHOD Run()
   {
+    FMRadioService* fmRadioService = FMRadioService::Singleton();
+    if (fmRadioService->mTuneThread) {
+      fmRadioService->mTuneThread->Shutdown();
+      fmRadioService->mTuneThread = nullptr;
+    }
     // Fix Bug 796733. DisableFMRadio should be called before
     // SetFmRadioAudioEnabled to prevent the annoying beep sound.
     DisableFMRadio();
-    IFMRadioService::Singleton()->EnableAudio(false);
+    fmRadioService->EnableAudio(false);
 
     return NS_OK;
   }
 };
 
 class SetFrequencyRunnable MOZ_FINAL : public nsRunnable
 {
 public:
@@ -293,17 +305,17 @@ FMRadioService::RemoveObserver(FMRadioEv
 {
   MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
   mObserverList.RemoveObserver(aObserver);
 
   if (mObserverList.Length() == 0)
   {
     // Turning off the FM radio HW because observer list is empty.
     if (IsFMRadioOn()) {
-      NS_DispatchToMainThread(new DisableRunnable());
+      DoDisable();
     }
   }
 }
 
 void
 FMRadioService::EnableAudio(bool aAudioEnabled)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@@ -590,17 +602,18 @@ FMRadioService::SetFrequency(double aFre
 
   if (!roundedFrequency) {
     aReplyRunnable->SetReply(ErrorResponse(
       NS_LITERAL_STRING("Frequency is out of range")));
     NS_DispatchToMainThread(aReplyRunnable);
     return;
   }
 
-  NS_DispatchToMainThread(new SetFrequencyRunnable(roundedFrequency));
+  mTuneThread->Dispatch(new SetFrequencyRunnable(roundedFrequency),
+                        nsIThread::DISPATCH_NORMAL);
 
   aReplyRunnable->SetReply(SuccessResponse());
   NS_DispatchToMainThread(aReplyRunnable);
 }
 
 void
 FMRadioService::Seek(FMRadioSeekDirection aDirection,
                      FMRadioReplyRunnable* aReplyRunnable)
@@ -631,17 +644,17 @@ FMRadioService::Seek(FMRadioSeekDirectio
       return;
     case Enabled:
       break;
   }
 
   SetState(Seeking);
   mPendingRequest = aReplyRunnable;
 
-  NS_DispatchToMainThread(new SeekRunnable(aDirection));
+  mTuneThread->Dispatch(new SeekRunnable(aDirection), nsIThread::DISPATCH_NORMAL);
 }
 
 void
 FMRadioService::CancelSeek(FMRadioReplyRunnable* aReplyRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
   MOZ_ASSERT(aReplyRunnable);
 
--- a/dom/fmradio/FMRadioService.h
+++ b/dom/fmradio/FMRadioService.h
@@ -136,17 +136,18 @@ enum FMRadioState
   Seeking
 };
 
 class FMRadioService MOZ_FINAL : public IFMRadioService
                                , public hal::FMRadioObserver
                                , public nsIObserver
 {
   friend class ReadAirplaneModeSettingTask;
-  friend class SetFrequencyRunnable;
+  friend class EnableRunnable;
+  friend class DisableRunnable;
 
 public:
   static FMRadioService* Singleton();
   virtual ~FMRadioService();
 
   NS_DECL_ISUPPORTS
 
   virtual bool IsEnabled() const MOZ_OVERRIDE;
@@ -197,16 +198,17 @@ private:
   bool mHasReadAirplaneModeSetting;
   bool mAirplaneModeEnabled;
 
   uint32_t mUpperBoundInKHz;
   uint32_t mLowerBoundInKHz;
   uint32_t mChannelWidthInKHz;
   uint32_t mPreemphasis;
 
+  nsCOMPtr<nsIThread> mTuneThread;
   nsRefPtr<FMRadioReplyRunnable> mPendingRequest;
 
   FMRadioEventObserverList mObserverList;
 
   static StaticRefPtr<FMRadioService> sFMRadioService;
 };
 
 END_FMRADIO_NAMESPACE