1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/fmradio/FMRadioService.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,214 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_fmradioservice_h__ 1.11 +#define mozilla_dom_fmradioservice_h__ 1.12 + 1.13 +#include "mozilla/dom/PFMRadioRequest.h" 1.14 +#include "FMRadioCommon.h" 1.15 +#include "mozilla/Hal.h" 1.16 +#include "mozilla/StaticPtr.h" 1.17 +#include "mozilla/Services.h" 1.18 +#include "nsThreadUtils.h" 1.19 +#include "nsIObserver.h" 1.20 +#include "nsXULAppAPI.h" 1.21 + 1.22 +BEGIN_FMRADIO_NAMESPACE 1.23 + 1.24 +class FMRadioReplyRunnable : public nsRunnable 1.25 +{ 1.26 +public: 1.27 + FMRadioReplyRunnable() : mResponseType(SuccessResponse()) {} 1.28 + virtual ~FMRadioReplyRunnable() {} 1.29 + 1.30 + void 1.31 + SetReply(const FMRadioResponseType& aResponseType) 1.32 + { 1.33 + mResponseType = aResponseType; 1.34 + } 1.35 + 1.36 +protected: 1.37 + FMRadioResponseType mResponseType; 1.38 +}; 1.39 + 1.40 +/** 1.41 + * The FMRadio Service Interface for FMRadio. 1.42 + * 1.43 + * There are two concrete classes which implement this interface: 1.44 + * - FMRadioService 1.45 + * It's used in the main process, implements all the logics about FM Radio. 1.46 + * 1.47 + * - FMRadioChild 1.48 + * It's used in subprocess. It's a kind of proxy which just sends all 1.49 + * the requests to main process through IPC channel. 1.50 + * 1.51 + * All the requests coming from the content page will be redirected to the 1.52 + * concrete class object. 1.53 + * 1.54 + * Consider navigator.mozFMRadio.enable(). Here is the call sequence: 1.55 + * - OOP 1.56 + * Child: 1.57 + * (1) Call navigator.mozFMRadio.enable(). 1.58 + * (2) Return a DOMRequest object, and call FMRadioChild.Enable() with a 1.59 + * FMRadioReplyRunnable object. 1.60 + * (3) Send IPC message to main process. 1.61 + * Parent: 1.62 + * (4) Call FMRadioService::Enable() with a FMRadioReplyRunnable object. 1.63 + * (5) Call hal::EnableFMRadio(). 1.64 + * (6) Notify FMRadioService object when FM radio HW is enabled. 1.65 + * (7) Dispatch the FMRadioReplyRunnable object created in (4). 1.66 + * (8) Send IPC message back to child process. 1.67 + * Child: 1.68 + * (9) Dispatch the FMRadioReplyRunnable object created in (2). 1.69 + * (10) Fire success callback of the DOMRequest Object created in (2). 1.70 + * _ _ _ _ _ _ _ _ _ _ _ _ _ _ 1.71 + * | OOP | 1.72 + * | | 1.73 + * Page FMRadio | FMRadioChild IPC | FMRadioService Hal 1.74 + * | (1) | | | | | | | 1.75 + * |----->| (2) | | | | | | 1.76 + * | |--------|--------->| (3) | | | | 1.77 + * | | | |-----------> | | (4) | | 1.78 + * | | | | |--|---------->| (5) | 1.79 + * | | | | | | |--------->| 1.80 + * | | | | | | | (6) | 1.81 + * | | | | | | (7) |<---------| 1.82 + * | | | | (8) |<-|-----------| | 1.83 + * | | (9) | |<----------- | | | | 1.84 + * | (10) |<-------|----------| | | | | 1.85 + * |<-----| | | | | | | 1.86 + * | | 1.87 + * |_ _ _ _ _ _ _ _ _ _ _ _ _ _| 1.88 + * - non-OOP 1.89 + * In non-OOP model, we don't need to send messages between processes, so 1.90 + * the call sequences are much more simpler, it almost just follows the 1.91 + * sequences presented in OOP model: (1) (2) (5) (6) (9) and (10). 1.92 + * 1.93 + */ 1.94 +class IFMRadioService 1.95 +{ 1.96 +protected: 1.97 + virtual ~IFMRadioService() { } 1.98 + 1.99 +public: 1.100 + virtual bool IsEnabled() const = 0; 1.101 + virtual double GetFrequency() const = 0; 1.102 + virtual double GetFrequencyUpperBound() const = 0; 1.103 + virtual double GetFrequencyLowerBound() const = 0; 1.104 + virtual double GetChannelWidth() const = 0; 1.105 + 1.106 + virtual void Enable(double aFrequency, FMRadioReplyRunnable* aReplyRunnable) = 0; 1.107 + virtual void Disable(FMRadioReplyRunnable* aReplyRunnable) = 0; 1.108 + virtual void SetFrequency(double aFrequency, FMRadioReplyRunnable* aReplyRunnable) = 0; 1.109 + virtual void Seek(mozilla::hal::FMRadioSeekDirection aDirection, 1.110 + FMRadioReplyRunnable* aReplyRunnable) = 0; 1.111 + virtual void CancelSeek(FMRadioReplyRunnable* aReplyRunnable) = 0; 1.112 + 1.113 + /** 1.114 + * Register handler to receive the FM Radio events, including: 1.115 + * - StateChangedEvent 1.116 + * - FrequencyChangedEvent 1.117 + * 1.118 + * Called by FMRadio and FMRadioParent. 1.119 + */ 1.120 + virtual void AddObserver(FMRadioEventObserver* aObserver) = 0; 1.121 + virtual void RemoveObserver(FMRadioEventObserver* aObserver) = 0; 1.122 + 1.123 + // Enable/Disable FMRadio 1.124 + virtual void EnableAudio(bool aAudioEnabled) = 0; 1.125 + 1.126 + /** 1.127 + * Static method to return the singleton instance. If it's in the child 1.128 + * process, we will get an object of FMRadioChild. 1.129 + */ 1.130 + static IFMRadioService* Singleton(); 1.131 +}; 1.132 + 1.133 +enum FMRadioState 1.134 +{ 1.135 + Disabled, 1.136 + Disabling, 1.137 + Enabling, 1.138 + Enabled, 1.139 + Seeking 1.140 +}; 1.141 + 1.142 +class FMRadioService MOZ_FINAL : public IFMRadioService 1.143 + , public hal::FMRadioObserver 1.144 + , public nsIObserver 1.145 +{ 1.146 + friend class ReadAirplaneModeSettingTask; 1.147 + friend class SetFrequencyRunnable; 1.148 + 1.149 +public: 1.150 + static FMRadioService* Singleton(); 1.151 + virtual ~FMRadioService(); 1.152 + 1.153 + NS_DECL_ISUPPORTS 1.154 + 1.155 + virtual bool IsEnabled() const MOZ_OVERRIDE; 1.156 + virtual double GetFrequency() const MOZ_OVERRIDE; 1.157 + virtual double GetFrequencyUpperBound() const MOZ_OVERRIDE; 1.158 + virtual double GetFrequencyLowerBound() const MOZ_OVERRIDE; 1.159 + virtual double GetChannelWidth() const MOZ_OVERRIDE; 1.160 + 1.161 + virtual void Enable(double aFrequency, 1.162 + FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; 1.163 + virtual void Disable(FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; 1.164 + virtual void SetFrequency(double aFrequency, 1.165 + FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; 1.166 + virtual void Seek(mozilla::hal::FMRadioSeekDirection aDirection, 1.167 + FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; 1.168 + virtual void CancelSeek(FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; 1.169 + 1.170 + virtual void AddObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; 1.171 + virtual void RemoveObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; 1.172 + 1.173 + virtual void EnableAudio(bool aAudioEnabled) MOZ_OVERRIDE; 1.174 + 1.175 + /* FMRadioObserver */ 1.176 + void Notify(const hal::FMRadioOperationInformation& aInfo) MOZ_OVERRIDE; 1.177 + 1.178 + NS_DECL_NSIOBSERVER 1.179 + 1.180 +protected: 1.181 + FMRadioService(); 1.182 + 1.183 +private: 1.184 + int32_t RoundFrequency(double aFrequencyInMHz); 1.185 + 1.186 + void NotifyFMRadioEvent(FMRadioEventType aType); 1.187 + void DoDisable(); 1.188 + void TransitionState(const FMRadioResponseType& aResponse, FMRadioState aState); 1.189 + void SetState(FMRadioState aState); 1.190 + void UpdatePowerState(); 1.191 + void UpdateFrequency(); 1.192 + 1.193 +private: 1.194 + bool mEnabled; 1.195 + 1.196 + int32_t mPendingFrequencyInKHz; 1.197 + 1.198 + FMRadioState mState; 1.199 + 1.200 + bool mHasReadAirplaneModeSetting; 1.201 + bool mAirplaneModeEnabled; 1.202 + 1.203 + double mUpperBoundInKHz; 1.204 + double mLowerBoundInKHz; 1.205 + double mChannelWidthInKHz; 1.206 + 1.207 + nsRefPtr<FMRadioReplyRunnable> mPendingRequest; 1.208 + 1.209 + FMRadioEventObserverList mObserverList; 1.210 + 1.211 + static StaticRefPtr<FMRadioService> sFMRadioService; 1.212 +}; 1.213 + 1.214 +END_FMRADIO_NAMESPACE 1.215 + 1.216 +#endif // mozilla_dom_fmradioservice_h__ 1.217 +