2013-09-04 02:26:33 +04:00
|
|
|
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_dom_fmradioservice_h__
|
|
|
|
#define mozilla_dom_fmradioservice_h__
|
|
|
|
|
2014-09-30 20:57:52 +04:00
|
|
|
#include "mozilla/dom/Nullable.h"
|
2013-09-04 02:26:33 +04:00
|
|
|
#include "mozilla/dom/PFMRadioRequest.h"
|
|
|
|
#include "FMRadioCommon.h"
|
|
|
|
#include "mozilla/Hal.h"
|
2014-09-30 20:57:52 +04:00
|
|
|
#include "mozilla/Mutex.h"
|
2013-09-04 02:26:33 +04:00
|
|
|
#include "mozilla/StaticPtr.h"
|
|
|
|
#include "mozilla/Services.h"
|
|
|
|
#include "nsThreadUtils.h"
|
2014-04-26 01:24:00 +04:00
|
|
|
#include "nsIObserver.h"
|
2013-09-04 02:26:33 +04:00
|
|
|
#include "nsXULAppAPI.h"
|
|
|
|
|
|
|
|
BEGIN_FMRADIO_NAMESPACE
|
|
|
|
|
2013-08-30 10:16:49 +04:00
|
|
|
class FMRadioReplyRunnable : public nsRunnable
|
2013-09-04 02:26:33 +04:00
|
|
|
{
|
|
|
|
public:
|
2013-08-30 10:16:49 +04:00
|
|
|
FMRadioReplyRunnable() : mResponseType(SuccessResponse()) {}
|
|
|
|
virtual ~FMRadioReplyRunnable() {}
|
2013-09-04 02:26:33 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
SetReply(const FMRadioResponseType& aResponseType)
|
|
|
|
{
|
|
|
|
mResponseType = aResponseType;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
FMRadioResponseType mResponseType;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The FMRadio Service Interface for FMRadio.
|
|
|
|
*
|
|
|
|
* There are two concrete classes which implement this interface:
|
|
|
|
* - FMRadioService
|
|
|
|
* It's used in the main process, implements all the logics about FM Radio.
|
|
|
|
*
|
|
|
|
* - FMRadioChild
|
|
|
|
* It's used in subprocess. It's a kind of proxy which just sends all
|
|
|
|
* the requests to main process through IPC channel.
|
|
|
|
*
|
|
|
|
* All the requests coming from the content page will be redirected to the
|
|
|
|
* concrete class object.
|
|
|
|
*
|
|
|
|
* Consider navigator.mozFMRadio.enable(). Here is the call sequence:
|
|
|
|
* - OOP
|
|
|
|
* Child:
|
|
|
|
* (1) Call navigator.mozFMRadio.enable().
|
|
|
|
* (2) Return a DOMRequest object, and call FMRadioChild.Enable() with a
|
2013-08-30 10:16:49 +04:00
|
|
|
* FMRadioReplyRunnable object.
|
2013-09-04 02:26:33 +04:00
|
|
|
* (3) Send IPC message to main process.
|
|
|
|
* Parent:
|
2013-08-30 10:16:49 +04:00
|
|
|
* (4) Call FMRadioService::Enable() with a FMRadioReplyRunnable object.
|
2013-09-04 02:26:33 +04:00
|
|
|
* (5) Call hal::EnableFMRadio().
|
|
|
|
* (6) Notify FMRadioService object when FM radio HW is enabled.
|
2013-08-30 10:16:49 +04:00
|
|
|
* (7) Dispatch the FMRadioReplyRunnable object created in (4).
|
2013-09-04 02:26:33 +04:00
|
|
|
* (8) Send IPC message back to child process.
|
|
|
|
* Child:
|
2013-08-30 10:16:49 +04:00
|
|
|
* (9) Dispatch the FMRadioReplyRunnable object created in (2).
|
2013-09-04 02:26:33 +04:00
|
|
|
* (10) Fire success callback of the DOMRequest Object created in (2).
|
|
|
|
* _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
|
* | OOP |
|
|
|
|
* | |
|
|
|
|
* Page FMRadio | FMRadioChild IPC | FMRadioService Hal
|
|
|
|
* | (1) | | | | | | |
|
|
|
|
* |----->| (2) | | | | | |
|
|
|
|
* | |--------|--------->| (3) | | | |
|
|
|
|
* | | | |-----------> | | (4) | |
|
|
|
|
* | | | | |--|---------->| (5) |
|
|
|
|
* | | | | | | |--------->|
|
|
|
|
* | | | | | | | (6) |
|
|
|
|
* | | | | | | (7) |<---------|
|
|
|
|
* | | | | (8) |<-|-----------| |
|
|
|
|
* | | (9) | |<----------- | | | |
|
|
|
|
* | (10) |<-------|----------| | | | |
|
|
|
|
* |<-----| | | | | | |
|
|
|
|
* | |
|
|
|
|
* |_ _ _ _ _ _ _ _ _ _ _ _ _ _|
|
|
|
|
* - non-OOP
|
|
|
|
* In non-OOP model, we don't need to send messages between processes, so
|
|
|
|
* the call sequences are much more simpler, it almost just follows the
|
|
|
|
* sequences presented in OOP model: (1) (2) (5) (6) (9) and (10).
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class IFMRadioService
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
virtual ~IFMRadioService() { }
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual bool IsEnabled() const = 0;
|
2014-09-30 20:57:52 +04:00
|
|
|
virtual bool IsRDSEnabled() const = 0;
|
2013-09-04 02:26:33 +04:00
|
|
|
virtual double GetFrequency() const = 0;
|
|
|
|
virtual double GetFrequencyUpperBound() const = 0;
|
|
|
|
virtual double GetFrequencyLowerBound() const = 0;
|
|
|
|
virtual double GetChannelWidth() const = 0;
|
2014-09-30 20:57:52 +04:00
|
|
|
virtual Nullable<unsigned short> GetPi() const = 0;
|
|
|
|
virtual Nullable<uint8_t> GetPty() const = 0;
|
|
|
|
virtual bool GetPs(nsString& aPsname) = 0;
|
|
|
|
virtual bool GetRt(nsString& aRadiotext) = 0;
|
|
|
|
virtual bool GetRdsgroup(uint64_t& aRDSGroup) = 0;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2013-08-30 10:16:49 +04:00
|
|
|
virtual void Enable(double aFrequency, FMRadioReplyRunnable* aReplyRunnable) = 0;
|
|
|
|
virtual void Disable(FMRadioReplyRunnable* aReplyRunnable) = 0;
|
|
|
|
virtual void SetFrequency(double aFrequency, FMRadioReplyRunnable* aReplyRunnable) = 0;
|
2013-09-04 02:26:33 +04:00
|
|
|
virtual void Seek(mozilla::hal::FMRadioSeekDirection aDirection,
|
2013-08-30 10:16:49 +04:00
|
|
|
FMRadioReplyRunnable* aReplyRunnable) = 0;
|
|
|
|
virtual void CancelSeek(FMRadioReplyRunnable* aReplyRunnable) = 0;
|
2014-09-30 20:57:52 +04:00
|
|
|
virtual void SetRDSGroupMask(uint32_t aRDSGroupMask) = 0;
|
|
|
|
virtual void EnableRDS(FMRadioReplyRunnable* aReplyRunnable) = 0;
|
|
|
|
virtual void DisableRDS(FMRadioReplyRunnable* aReplyRunnable) = 0;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Register handler to receive the FM Radio events, including:
|
|
|
|
* - StateChangedEvent
|
|
|
|
* - FrequencyChangedEvent
|
|
|
|
*
|
|
|
|
* Called by FMRadio and FMRadioParent.
|
|
|
|
*/
|
|
|
|
virtual void AddObserver(FMRadioEventObserver* aObserver) = 0;
|
|
|
|
virtual void RemoveObserver(FMRadioEventObserver* aObserver) = 0;
|
|
|
|
|
2013-11-05 02:27:39 +04:00
|
|
|
// Enable/Disable FMRadio
|
|
|
|
virtual void EnableAudio(bool aAudioEnabled) = 0;
|
|
|
|
|
2013-09-04 02:26:33 +04:00
|
|
|
/**
|
|
|
|
* Static method to return the singleton instance. If it's in the child
|
|
|
|
* process, we will get an object of FMRadioChild.
|
|
|
|
*/
|
|
|
|
static IFMRadioService* Singleton();
|
|
|
|
};
|
|
|
|
|
|
|
|
enum FMRadioState
|
|
|
|
{
|
|
|
|
Disabled,
|
|
|
|
Disabling,
|
|
|
|
Enabling,
|
|
|
|
Enabled,
|
|
|
|
Seeking
|
|
|
|
};
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class FMRadioService final : public IFMRadioService
|
2013-09-04 02:26:33 +04:00
|
|
|
, public hal::FMRadioObserver
|
2014-09-30 20:57:52 +04:00
|
|
|
, public hal::FMRadioRDSObserver
|
2014-04-26 01:24:00 +04:00
|
|
|
, public nsIObserver
|
2013-09-04 02:26:33 +04:00
|
|
|
{
|
2014-04-26 01:24:00 +04:00
|
|
|
friend class ReadAirplaneModeSettingTask;
|
2014-07-15 01:56:10 +04:00
|
|
|
friend class EnableRunnable;
|
|
|
|
friend class DisableRunnable;
|
2014-09-30 20:57:52 +04:00
|
|
|
friend class NotifyRunnable;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
|
|
|
public:
|
|
|
|
static FMRadioService* Singleton();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool IsEnabled() const override;
|
|
|
|
virtual bool IsRDSEnabled() const override;
|
|
|
|
virtual double GetFrequency() const override;
|
|
|
|
virtual double GetFrequencyUpperBound() const override;
|
|
|
|
virtual double GetFrequencyLowerBound() const override;
|
|
|
|
virtual double GetChannelWidth() const override;
|
|
|
|
virtual Nullable<unsigned short> GetPi() const override;
|
|
|
|
virtual Nullable<uint8_t> GetPty() const override;
|
|
|
|
virtual bool GetPs(nsString& aPsname) override;
|
|
|
|
virtual bool GetRt(nsString& aRadiotext) override;
|
|
|
|
virtual bool GetRdsgroup(uint64_t& aRDSGroup) override;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2013-08-30 10:16:49 +04:00
|
|
|
virtual void Enable(double aFrequency,
|
2015-03-21 19:28:04 +03:00
|
|
|
FMRadioReplyRunnable* aReplyRunnable) override;
|
|
|
|
virtual void Disable(FMRadioReplyRunnable* aReplyRunnable) override;
|
2013-08-30 10:16:49 +04:00
|
|
|
virtual void SetFrequency(double aFrequency,
|
2015-03-21 19:28:04 +03:00
|
|
|
FMRadioReplyRunnable* aReplyRunnable) override;
|
2013-09-04 02:26:33 +04:00
|
|
|
virtual void Seek(mozilla::hal::FMRadioSeekDirection aDirection,
|
2015-03-21 19:28:04 +03:00
|
|
|
FMRadioReplyRunnable* aReplyRunnable) override;
|
|
|
|
virtual void CancelSeek(FMRadioReplyRunnable* aReplyRunnable) override;
|
|
|
|
virtual void SetRDSGroupMask(uint32_t aRDSGroupMask) override;
|
|
|
|
virtual void EnableRDS(FMRadioReplyRunnable* aReplyRunnable) override;
|
|
|
|
virtual void DisableRDS(FMRadioReplyRunnable* aReplyRunnable) override;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual void AddObserver(FMRadioEventObserver* aObserver) override;
|
|
|
|
virtual void RemoveObserver(FMRadioEventObserver* aObserver) override;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual void EnableAudio(bool aAudioEnabled) override;
|
2013-11-05 02:27:39 +04:00
|
|
|
|
2013-09-04 02:26:33 +04:00
|
|
|
/* FMRadioObserver */
|
2015-03-21 19:28:04 +03:00
|
|
|
void Notify(const hal::FMRadioOperationInformation& aInfo) override;
|
2014-09-30 20:57:52 +04:00
|
|
|
/* FMRadioRDSObserver */
|
2015-03-21 19:28:04 +03:00
|
|
|
void Notify(const hal::FMRadioRDSGroup& aRDSGroup) override;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2014-04-26 01:24:00 +04:00
|
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
|
2013-09-04 02:26:33 +04:00
|
|
|
protected:
|
|
|
|
FMRadioService();
|
2015-03-10 15:44:02 +03:00
|
|
|
virtual ~FMRadioService();
|
2013-09-04 02:26:33 +04:00
|
|
|
|
|
|
|
private:
|
|
|
|
int32_t RoundFrequency(double aFrequencyInMHz);
|
|
|
|
|
|
|
|
void NotifyFMRadioEvent(FMRadioEventType aType);
|
|
|
|
void DoDisable();
|
|
|
|
void TransitionState(const FMRadioResponseType& aResponse, FMRadioState aState);
|
|
|
|
void SetState(FMRadioState aState);
|
|
|
|
void UpdatePowerState();
|
|
|
|
void UpdateFrequency();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool mEnabled;
|
|
|
|
|
|
|
|
int32_t mPendingFrequencyInKHz;
|
|
|
|
|
|
|
|
FMRadioState mState;
|
|
|
|
|
2014-04-26 01:24:00 +04:00
|
|
|
bool mHasReadAirplaneModeSetting;
|
|
|
|
bool mAirplaneModeEnabled;
|
2014-09-30 20:57:52 +04:00
|
|
|
bool mRDSEnabled;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2014-07-14 21:06:19 +04:00
|
|
|
uint32_t mUpperBoundInKHz;
|
|
|
|
uint32_t mLowerBoundInKHz;
|
|
|
|
uint32_t mChannelWidthInKHz;
|
|
|
|
uint32_t mPreemphasis;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
2014-07-15 01:56:10 +04:00
|
|
|
nsCOMPtr<nsIThread> mTuneThread;
|
2013-08-30 10:16:49 +04:00
|
|
|
nsRefPtr<FMRadioReplyRunnable> mPendingRequest;
|
2013-09-04 02:26:33 +04:00
|
|
|
|
|
|
|
FMRadioEventObserverList mObserverList;
|
|
|
|
|
|
|
|
static StaticRefPtr<FMRadioService> sFMRadioService;
|
2014-09-30 20:57:52 +04:00
|
|
|
|
|
|
|
uint32_t mRDSGroupMask;
|
|
|
|
|
|
|
|
uint16_t mLastPI;
|
|
|
|
uint16_t mLastPTY;
|
|
|
|
Atomic<uint32_t> mPI;
|
|
|
|
Atomic<uint32_t> mPTY;
|
|
|
|
Atomic<bool> mPISet;
|
|
|
|
Atomic<bool> mPTYSet;
|
|
|
|
|
|
|
|
/* Protects mPSName, mRadiotext, and mRDSGroup */
|
|
|
|
Mutex mRDSLock;
|
|
|
|
char16_t mPSName[9];
|
|
|
|
char16_t mRadiotext[65];
|
|
|
|
uint64_t mRDSGroup;
|
|
|
|
|
|
|
|
uint8_t mPSNameState;
|
|
|
|
uint16_t mRadiotextState;
|
|
|
|
uint16_t mTempPSName[8];
|
|
|
|
uint16_t mTempRadiotext[64];
|
|
|
|
bool mRadiotextAB;
|
|
|
|
bool mRDSGroupSet;
|
|
|
|
bool mPSNameSet;
|
|
|
|
bool mRadiotextSet;
|
2013-09-04 02:26:33 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
END_FMRADIO_NAMESPACE
|
|
|
|
|
|
|
|
#endif // mozilla_dom_fmradioservice_h__
|
|
|
|
|