Bug 938809 - Run seek/tune calls off the main thread, r=pzhang,khuey
--- 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