|
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ |
|
2 /* vim: set ts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef mozilla_dom_fmradioservice_h__ |
|
8 #define mozilla_dom_fmradioservice_h__ |
|
9 |
|
10 #include "mozilla/dom/PFMRadioRequest.h" |
|
11 #include "FMRadioCommon.h" |
|
12 #include "mozilla/Hal.h" |
|
13 #include "mozilla/StaticPtr.h" |
|
14 #include "mozilla/Services.h" |
|
15 #include "nsThreadUtils.h" |
|
16 #include "nsIObserver.h" |
|
17 #include "nsXULAppAPI.h" |
|
18 |
|
19 BEGIN_FMRADIO_NAMESPACE |
|
20 |
|
21 class FMRadioReplyRunnable : public nsRunnable |
|
22 { |
|
23 public: |
|
24 FMRadioReplyRunnable() : mResponseType(SuccessResponse()) {} |
|
25 virtual ~FMRadioReplyRunnable() {} |
|
26 |
|
27 void |
|
28 SetReply(const FMRadioResponseType& aResponseType) |
|
29 { |
|
30 mResponseType = aResponseType; |
|
31 } |
|
32 |
|
33 protected: |
|
34 FMRadioResponseType mResponseType; |
|
35 }; |
|
36 |
|
37 /** |
|
38 * The FMRadio Service Interface for FMRadio. |
|
39 * |
|
40 * There are two concrete classes which implement this interface: |
|
41 * - FMRadioService |
|
42 * It's used in the main process, implements all the logics about FM Radio. |
|
43 * |
|
44 * - FMRadioChild |
|
45 * It's used in subprocess. It's a kind of proxy which just sends all |
|
46 * the requests to main process through IPC channel. |
|
47 * |
|
48 * All the requests coming from the content page will be redirected to the |
|
49 * concrete class object. |
|
50 * |
|
51 * Consider navigator.mozFMRadio.enable(). Here is the call sequence: |
|
52 * - OOP |
|
53 * Child: |
|
54 * (1) Call navigator.mozFMRadio.enable(). |
|
55 * (2) Return a DOMRequest object, and call FMRadioChild.Enable() with a |
|
56 * FMRadioReplyRunnable object. |
|
57 * (3) Send IPC message to main process. |
|
58 * Parent: |
|
59 * (4) Call FMRadioService::Enable() with a FMRadioReplyRunnable object. |
|
60 * (5) Call hal::EnableFMRadio(). |
|
61 * (6) Notify FMRadioService object when FM radio HW is enabled. |
|
62 * (7) Dispatch the FMRadioReplyRunnable object created in (4). |
|
63 * (8) Send IPC message back to child process. |
|
64 * Child: |
|
65 * (9) Dispatch the FMRadioReplyRunnable object created in (2). |
|
66 * (10) Fire success callback of the DOMRequest Object created in (2). |
|
67 * _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|
68 * | OOP | |
|
69 * | | |
|
70 * Page FMRadio | FMRadioChild IPC | FMRadioService Hal |
|
71 * | (1) | | | | | | | |
|
72 * |----->| (2) | | | | | | |
|
73 * | |--------|--------->| (3) | | | | |
|
74 * | | | |-----------> | | (4) | | |
|
75 * | | | | |--|---------->| (5) | |
|
76 * | | | | | | |--------->| |
|
77 * | | | | | | | (6) | |
|
78 * | | | | | | (7) |<---------| |
|
79 * | | | | (8) |<-|-----------| | |
|
80 * | | (9) | |<----------- | | | | |
|
81 * | (10) |<-------|----------| | | | | |
|
82 * |<-----| | | | | | | |
|
83 * | | |
|
84 * |_ _ _ _ _ _ _ _ _ _ _ _ _ _| |
|
85 * - non-OOP |
|
86 * In non-OOP model, we don't need to send messages between processes, so |
|
87 * the call sequences are much more simpler, it almost just follows the |
|
88 * sequences presented in OOP model: (1) (2) (5) (6) (9) and (10). |
|
89 * |
|
90 */ |
|
91 class IFMRadioService |
|
92 { |
|
93 protected: |
|
94 virtual ~IFMRadioService() { } |
|
95 |
|
96 public: |
|
97 virtual bool IsEnabled() const = 0; |
|
98 virtual double GetFrequency() const = 0; |
|
99 virtual double GetFrequencyUpperBound() const = 0; |
|
100 virtual double GetFrequencyLowerBound() const = 0; |
|
101 virtual double GetChannelWidth() const = 0; |
|
102 |
|
103 virtual void Enable(double aFrequency, FMRadioReplyRunnable* aReplyRunnable) = 0; |
|
104 virtual void Disable(FMRadioReplyRunnable* aReplyRunnable) = 0; |
|
105 virtual void SetFrequency(double aFrequency, FMRadioReplyRunnable* aReplyRunnable) = 0; |
|
106 virtual void Seek(mozilla::hal::FMRadioSeekDirection aDirection, |
|
107 FMRadioReplyRunnable* aReplyRunnable) = 0; |
|
108 virtual void CancelSeek(FMRadioReplyRunnable* aReplyRunnable) = 0; |
|
109 |
|
110 /** |
|
111 * Register handler to receive the FM Radio events, including: |
|
112 * - StateChangedEvent |
|
113 * - FrequencyChangedEvent |
|
114 * |
|
115 * Called by FMRadio and FMRadioParent. |
|
116 */ |
|
117 virtual void AddObserver(FMRadioEventObserver* aObserver) = 0; |
|
118 virtual void RemoveObserver(FMRadioEventObserver* aObserver) = 0; |
|
119 |
|
120 // Enable/Disable FMRadio |
|
121 virtual void EnableAudio(bool aAudioEnabled) = 0; |
|
122 |
|
123 /** |
|
124 * Static method to return the singleton instance. If it's in the child |
|
125 * process, we will get an object of FMRadioChild. |
|
126 */ |
|
127 static IFMRadioService* Singleton(); |
|
128 }; |
|
129 |
|
130 enum FMRadioState |
|
131 { |
|
132 Disabled, |
|
133 Disabling, |
|
134 Enabling, |
|
135 Enabled, |
|
136 Seeking |
|
137 }; |
|
138 |
|
139 class FMRadioService MOZ_FINAL : public IFMRadioService |
|
140 , public hal::FMRadioObserver |
|
141 , public nsIObserver |
|
142 { |
|
143 friend class ReadAirplaneModeSettingTask; |
|
144 friend class SetFrequencyRunnable; |
|
145 |
|
146 public: |
|
147 static FMRadioService* Singleton(); |
|
148 virtual ~FMRadioService(); |
|
149 |
|
150 NS_DECL_ISUPPORTS |
|
151 |
|
152 virtual bool IsEnabled() const MOZ_OVERRIDE; |
|
153 virtual double GetFrequency() const MOZ_OVERRIDE; |
|
154 virtual double GetFrequencyUpperBound() const MOZ_OVERRIDE; |
|
155 virtual double GetFrequencyLowerBound() const MOZ_OVERRIDE; |
|
156 virtual double GetChannelWidth() const MOZ_OVERRIDE; |
|
157 |
|
158 virtual void Enable(double aFrequency, |
|
159 FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; |
|
160 virtual void Disable(FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; |
|
161 virtual void SetFrequency(double aFrequency, |
|
162 FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; |
|
163 virtual void Seek(mozilla::hal::FMRadioSeekDirection aDirection, |
|
164 FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; |
|
165 virtual void CancelSeek(FMRadioReplyRunnable* aReplyRunnable) MOZ_OVERRIDE; |
|
166 |
|
167 virtual void AddObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; |
|
168 virtual void RemoveObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; |
|
169 |
|
170 virtual void EnableAudio(bool aAudioEnabled) MOZ_OVERRIDE; |
|
171 |
|
172 /* FMRadioObserver */ |
|
173 void Notify(const hal::FMRadioOperationInformation& aInfo) MOZ_OVERRIDE; |
|
174 |
|
175 NS_DECL_NSIOBSERVER |
|
176 |
|
177 protected: |
|
178 FMRadioService(); |
|
179 |
|
180 private: |
|
181 int32_t RoundFrequency(double aFrequencyInMHz); |
|
182 |
|
183 void NotifyFMRadioEvent(FMRadioEventType aType); |
|
184 void DoDisable(); |
|
185 void TransitionState(const FMRadioResponseType& aResponse, FMRadioState aState); |
|
186 void SetState(FMRadioState aState); |
|
187 void UpdatePowerState(); |
|
188 void UpdateFrequency(); |
|
189 |
|
190 private: |
|
191 bool mEnabled; |
|
192 |
|
193 int32_t mPendingFrequencyInKHz; |
|
194 |
|
195 FMRadioState mState; |
|
196 |
|
197 bool mHasReadAirplaneModeSetting; |
|
198 bool mAirplaneModeEnabled; |
|
199 |
|
200 double mUpperBoundInKHz; |
|
201 double mLowerBoundInKHz; |
|
202 double mChannelWidthInKHz; |
|
203 |
|
204 nsRefPtr<FMRadioReplyRunnable> mPendingRequest; |
|
205 |
|
206 FMRadioEventObserverList mObserverList; |
|
207 |
|
208 static StaticRefPtr<FMRadioService> sFMRadioService; |
|
209 }; |
|
210 |
|
211 END_FMRADIO_NAMESPACE |
|
212 |
|
213 #endif // mozilla_dom_fmradioservice_h__ |
|
214 |