1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/TVServiceRunnables.h"
8 #include "mozilla/dom/TVTypes.h"
10 #include "nsIMutableArray.h"
12 #include "nsServiceManagerUtils.h"
14 #include "FakeTVService.h"
19 NS_IMPL_CYCLE_COLLECTION_CLASS(FakeTVService
)
21 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FakeTVService
)
22 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceListener
)
23 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTuners
)
24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannels
)
25 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrograms
)
26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEITBroadcastedTimer
)
27 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScanCompleteTimer
)
28 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
30 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FakeTVService
)
32 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceListener
)
33 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTuners
)
34 NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannels
)
35 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrograms
)
36 NS_IMPL_CYCLE_COLLECTION_UNLINK(mEITBroadcastedTimer
)
37 NS_IMPL_CYCLE_COLLECTION_UNLINK(mScanCompleteTimer
)
38 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
40 NS_IMPL_CYCLE_COLLECTING_ADDREF(FakeTVService
)
41 NS_IMPL_CYCLE_COLLECTING_RELEASE(FakeTVService
)
43 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FakeTVService
)
44 NS_INTERFACE_MAP_ENTRY(nsITVService
)
45 NS_INTERFACE_MAP_ENTRY(nsISupports
)
48 FakeTVService::FakeTVService()
53 FakeTVService::~FakeTVService()
61 const char* sourceTypes1
[2] = {"dvb-t", "dvb-c"};
62 nsCOMPtr
<nsITVTunerData
> tunerData1
= MockTuner(NS_LITERAL_STRING("1"), 2, sourceTypes1
);
63 mTuners
.AppendElement(tunerData1
);
64 const char* sourceTypes2
[1] = {"dvb-s"};
65 nsCOMPtr
<nsITVTunerData
> tunerData2
= MockTuner(NS_LITERAL_STRING("2"), 1, sourceTypes2
);
66 mTuners
.AppendElement(tunerData2
);
68 nsCOMPtr
<nsITVChannelData
> channelData1
=
69 MockChannel(NS_LITERAL_STRING("networkId1"), NS_LITERAL_STRING("transportStreamId1"),
70 NS_LITERAL_STRING("serviceId1"), NS_LITERAL_STRING("tv"),
71 NS_LITERAL_STRING("1"), NS_LITERAL_STRING("name1"), true, true);
72 mChannels
.AppendElement(channelData1
);
73 nsCOMPtr
<nsITVChannelData
> channelData2
=
74 MockChannel(NS_LITERAL_STRING("networkId2"), NS_LITERAL_STRING("transportStreamId2"),
75 NS_LITERAL_STRING("serviceId2"), NS_LITERAL_STRING("radio"),
76 NS_LITERAL_STRING("2"), NS_LITERAL_STRING("name2"), true, true);
77 mChannels
.AppendElement(channelData2
);
79 uint64_t now
= PR_Now();
80 const char* audioLanguages1
[2] = {"eng", "jpn"};
81 const char* subtitleLanguages1
[2] = {"fre", "spa"};
82 nsCOMPtr
<nsITVProgramData
> programData1
=
83 MockProgram(NS_LITERAL_STRING("eventId1"), NS_LITERAL_STRING("title1"),
85 NS_LITERAL_STRING("description1"), NS_LITERAL_STRING("rating1"),
86 2, audioLanguages1
, 2, subtitleLanguages1
);
87 mPrograms
.AppendElement(programData1
);
88 nsCOMPtr
<nsITVProgramData
> programData2
=
89 MockProgram(NS_LITERAL_STRING("eventId2"), NS_LITERAL_STRING("title2"),
90 now
+ 3600000 , 3600000,
91 NS_LITERAL_STRING(""), NS_LITERAL_STRING(""),
92 0, nullptr, 0, nullptr);
93 mPrograms
.AppendElement(programData2
);
97 FakeTVService::Shutdown()
99 if (mEITBroadcastedTimer
) {
100 mEITBroadcastedTimer
->Cancel();
102 if (mScanCompleteTimer
) {
103 mScanCompleteTimer
->Cancel();
107 /* virtual */ NS_IMETHODIMP
108 FakeTVService::GetSourceListener(nsITVSourceListener
** aSourceListener
)
110 if (!mSourceListener
) {
111 *aSourceListener
= nullptr;
115 *aSourceListener
= mSourceListener
;
116 NS_ADDREF(*aSourceListener
);
120 /* virtual */ NS_IMETHODIMP
121 FakeTVService::SetSourceListener(nsITVSourceListener
* aSourceListener
)
123 mSourceListener
= aSourceListener
;
127 /* virtual */ NS_IMETHODIMP
128 FakeTVService::GetTuners(nsITVServiceCallback
* aCallback
)
131 return NS_ERROR_INVALID_ARG
;
134 nsCOMPtr
<nsIMutableArray
> tunerDataList
= do_CreateInstance(NS_ARRAY_CONTRACTID
);
135 if (!tunerDataList
) {
136 return NS_ERROR_OUT_OF_MEMORY
;
139 for (uint32_t i
= 0; i
< mTuners
.Length(); i
++) {
140 tunerDataList
->AppendElement(mTuners
[i
], false);
143 nsCOMPtr
<nsIRunnable
> runnable
=
144 new TVServiceNotifyRunnable(aCallback
, tunerDataList
);
145 return NS_DispatchToCurrentThread(runnable
);
148 /* virtual */ NS_IMETHODIMP
149 FakeTVService::SetSource(const nsAString
& aTunerId
,
150 const nsAString
& aSourceType
,
151 nsITVServiceCallback
* aCallback
)
154 return NS_ERROR_INVALID_ARG
;
157 for (uint32_t i
= 0; i
< mTuners
.Length(); i
++) {
159 mTuners
[i
]->GetId(tunerId
);
160 if (aTunerId
.Equals(tunerId
)) {
161 uint32_t sourceTypeCount
;
163 mTuners
[i
]->GetSupportedSourceTypes(&sourceTypeCount
, &sourceTypes
);
164 for (uint32_t j
= 0; j
< sourceTypeCount
; j
++) {
166 sourceType
.AssignASCII(sourceTypes
[j
]);
167 if (aSourceType
.Equals(sourceType
)) {
168 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(sourceTypeCount
, sourceTypes
);
169 nsCOMPtr
<nsIRunnable
> runnable
=
170 new TVServiceNotifyRunnable(aCallback
, nullptr);
171 return NS_DispatchToCurrentThread(runnable
);
174 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(sourceTypeCount
, sourceTypes
);
178 nsCOMPtr
<nsIRunnable
> runnable
=
179 new TVServiceNotifyRunnable(aCallback
, nullptr, nsITVServiceCallback::TV_ERROR_FAILURE
);
180 return NS_DispatchToCurrentThread(runnable
);
183 class EITBroadcastedCallback MOZ_FINAL
: public nsITimerCallback
188 EITBroadcastedCallback(const nsAString
& aTunerId
,
189 const nsAString
& aSourceType
,
190 nsITVSourceListener
* aSourceListener
,
191 nsITVChannelData
* aChannelData
)
193 , mSourceType(aSourceType
)
194 , mSourceListener(aSourceListener
)
195 , mChannelData(aChannelData
)
199 Notify(nsITimer
* aTimer
) MOZ_OVERRIDE
201 // Notify mock EIT broadcasting.
202 nsITVProgramData
** programDataList
=
203 static_cast<nsITVProgramData
**>(NS_Alloc(1 * sizeof(nsITVProgramData
*)));
204 programDataList
[0] = new TVProgramData();
205 programDataList
[0]->SetEventId(NS_LITERAL_STRING("eventId"));
206 programDataList
[0]->SetTitle(NS_LITERAL_STRING("title"));
207 programDataList
[0]->SetStartTime(PR_Now() + 3600000);
208 programDataList
[0]->SetDuration(3600000);
209 programDataList
[0]->SetDescription(NS_LITERAL_STRING("description"));
210 programDataList
[0]->SetRating(NS_LITERAL_STRING("rating"));
211 programDataList
[0]->SetAudioLanguages(0, nullptr);
212 programDataList
[0]->SetSubtitleLanguages(0, nullptr);
213 nsresult rv
= mSourceListener
->NotifyEITBroadcasted(mTunerId
, mSourceType
,
216 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, programDataList
);
221 ~EITBroadcastedCallback() {}
224 nsString mSourceType
;
225 nsCOMPtr
<nsITVSourceListener
> mSourceListener
;
226 nsCOMPtr
<nsITVChannelData
> mChannelData
;
229 NS_IMPL_ISUPPORTS(EITBroadcastedCallback
, nsITimerCallback
)
231 class ScanCompleteCallback MOZ_FINAL
: public nsITimerCallback
236 ScanCompleteCallback(const nsAString
& aTunerId
,
237 const nsAString
& aSourceType
,
238 nsITVSourceListener
* aSourceListener
)
240 , mSourceType(aSourceType
)
241 , mSourceListener(aSourceListener
)
245 Notify(nsITimer
* aTimer
) MOZ_OVERRIDE
247 return mSourceListener
->NotifyChannelScanComplete(mTunerId
, mSourceType
);
251 ~ScanCompleteCallback() {}
254 nsString mSourceType
;
255 nsCOMPtr
<nsITVSourceListener
> mSourceListener
;
258 NS_IMPL_ISUPPORTS(ScanCompleteCallback
, nsITimerCallback
)
260 /* virtual */ NS_IMETHODIMP
261 FakeTVService::StartScanningChannels(const nsAString
& aTunerId
,
262 const nsAString
& aSourceType
,
263 nsITVServiceCallback
* aCallback
)
266 return NS_ERROR_INVALID_ARG
;
269 nsCOMPtr
<nsIRunnable
> runnable
=
270 new TVServiceNotifyRunnable(aCallback
, nullptr);
271 nsresult rv
= NS_DispatchToCurrentThread(runnable
);
272 NS_ENSURE_SUCCESS(rv
, rv
);
274 if (IsAllowed(aTunerId
, aSourceType
)) {
275 rv
= mSourceListener
->NotifyChannelScanned(aTunerId
, aSourceType
, mChannels
[0]);
276 NS_ENSURE_SUCCESS(rv
, rv
);
278 // Set a timer. |notifyEITBroadcasted| will be called after the timer
279 // fires (10ms). (The timer could be canceled if |StopScanningChannels| gets
280 // called before firing.)
281 mEITBroadcastedTimer
= do_CreateInstance(NS_TIMER_CONTRACTID
);
282 NS_ENSURE_TRUE(mEITBroadcastedTimer
, NS_ERROR_OUT_OF_MEMORY
);
283 nsRefPtr
<EITBroadcastedCallback
> eitBroadcastedCb
=
284 new EITBroadcastedCallback(aTunerId
, aSourceType
, mSourceListener
, mChannels
[0]);
285 rv
= mEITBroadcastedTimer
->InitWithCallback(eitBroadcastedCb
, 10,
286 nsITimer::TYPE_ONE_SHOT
);
287 NS_ENSURE_SUCCESS(rv
, rv
);
289 // Set a timer. |notifyChannelScanComplete| will be called after the timer
290 // fires (20ms). (The timer could be canceled if |StopScanningChannels| gets
291 // called before firing.)
292 mScanCompleteTimer
= do_CreateInstance(NS_TIMER_CONTRACTID
);
293 NS_ENSURE_TRUE(mScanCompleteTimer
, NS_ERROR_OUT_OF_MEMORY
);
294 nsRefPtr
<ScanCompleteCallback
> scanCompleteCb
=
295 new ScanCompleteCallback(aTunerId
, aSourceType
, mSourceListener
);
296 rv
= mScanCompleteTimer
->InitWithCallback(scanCompleteCb
, 20,
297 nsITimer::TYPE_ONE_SHOT
);
298 NS_ENSURE_SUCCESS(rv
, rv
);
304 /* virtual */ NS_IMETHODIMP
305 FakeTVService::StopScanningChannels(const nsAString
& aTunerId
,
306 const nsAString
& aSourceType
,
307 nsITVServiceCallback
* aCallback
)
310 return NS_ERROR_INVALID_ARG
;
313 if (mEITBroadcastedTimer
) {
314 mEITBroadcastedTimer
->Cancel();
315 mEITBroadcastedTimer
= nullptr;
317 if (mScanCompleteTimer
) {
318 mScanCompleteTimer
->Cancel();
319 mScanCompleteTimer
= nullptr;
321 nsresult rv
= mSourceListener
->NotifyChannelScanStopped(aTunerId
, aSourceType
);
322 NS_ENSURE_SUCCESS(rv
, rv
);
324 nsCOMPtr
<nsIRunnable
> runnable
=
325 new TVServiceNotifyRunnable(aCallback
, nullptr);
326 return NS_DispatchToCurrentThread(runnable
);
329 /* virtual */ NS_IMETHODIMP
330 FakeTVService::ClearScannedChannelsCache()
332 // Fake service doesn't support channel cache, so there's nothing to do here.
336 /* virtual */ NS_IMETHODIMP
337 FakeTVService::SetChannel(const nsAString
& aTunerId
,
338 const nsAString
& aSourceType
,
339 const nsAString
& aChannelNumber
,
340 nsITVServiceCallback
* aCallback
)
343 return NS_ERROR_INVALID_ARG
;
346 nsCOMPtr
<nsIMutableArray
> channelDataList
= do_CreateInstance(NS_ARRAY_CONTRACTID
);
347 if (!channelDataList
) {
348 return NS_ERROR_OUT_OF_MEMORY
;
351 if (IsAllowed(aTunerId
, aSourceType
)) {
352 for (uint32_t i
= 0; i
< mChannels
.Length(); i
++) {
353 nsString channelNumber
;
354 mChannels
[i
]->GetNumber(channelNumber
);
355 if (aChannelNumber
.Equals(channelNumber
)) {
356 channelDataList
->AppendElement(mChannels
[i
], false);
363 nsresult rv
= channelDataList
->GetLength(&length
);
364 NS_ENSURE_SUCCESS(rv
, rv
);
366 nsCOMPtr
<nsIRunnable
> runnable
= new TVServiceNotifyRunnable(
368 (length
== 1) ? channelDataList
: nullptr,
369 (length
== 1) ? nsITVServiceCallback::TV_ERROR_OK
: nsITVServiceCallback::TV_ERROR_FAILURE
371 return NS_DispatchToCurrentThread(runnable
);
374 /* virtual */ NS_IMETHODIMP
375 FakeTVService::GetChannels(const nsAString
& aTunerId
,
376 const nsAString
& aSourceType
,
377 nsITVServiceCallback
* aCallback
)
380 return NS_ERROR_INVALID_ARG
;
383 nsCOMPtr
<nsIMutableArray
> channelDataList
= do_CreateInstance(NS_ARRAY_CONTRACTID
);
384 if (!channelDataList
) {
385 return NS_ERROR_OUT_OF_MEMORY
;
388 if (IsAllowed(aTunerId
, aSourceType
)) {
389 for (uint32_t i
= 0; i
< mChannels
.Length(); i
++) {
390 channelDataList
->AppendElement(mChannels
[i
], false);
394 nsCOMPtr
<nsIRunnable
> runnable
=
395 new TVServiceNotifyRunnable(aCallback
, channelDataList
);
396 return NS_DispatchToCurrentThread(runnable
);
399 /* virtual */ NS_IMETHODIMP
400 FakeTVService::GetPrograms(const nsAString
& aTunerId
,
401 const nsAString
& aSourceType
,
402 const nsAString
& aChannelNumber
,
405 nsITVServiceCallback
* aCallback
)
408 return NS_ERROR_INVALID_ARG
;
411 nsCOMPtr
<nsIMutableArray
> programDataList
= do_CreateInstance(NS_ARRAY_CONTRACTID
);
412 if (!programDataList
) {
413 return NS_ERROR_OUT_OF_MEMORY
;
416 // Only return mock programs for the first channel.
417 nsString channelNumber
;
418 mChannels
[0]->GetNumber(channelNumber
);
419 if (IsAllowed(aTunerId
, aSourceType
) && aChannelNumber
.Equals(channelNumber
)) {
420 for (uint32_t i
= 0; i
< mPrograms
.Length(); i
++) {
421 programDataList
->AppendElement(mPrograms
[i
], false);
425 nsCOMPtr
<nsIRunnable
> runnable
=
426 new TVServiceNotifyRunnable(aCallback
, programDataList
);
427 return NS_DispatchToCurrentThread(runnable
);
430 /* virtual */ NS_IMETHODIMP
431 FakeTVService::GetOverlayId(const nsAString
& aTunerId
,
432 nsITVServiceCallback
* aCallback
)
435 return NS_ERROR_INVALID_ARG
;
438 nsCOMPtr
<nsIMutableArray
> overlayIds
= do_CreateInstance(NS_ARRAY_CONTRACTID
);
440 return NS_ERROR_OUT_OF_MEMORY
;
443 // TODO Implement in follow-up patches.
445 nsCOMPtr
<nsIRunnable
> runnable
=
446 new TVServiceNotifyRunnable(aCallback
, overlayIds
);
447 return NS_DispatchToCurrentThread(runnable
);
451 FakeTVService::IsAllowed(const nsAString
& aTunerId
,
452 const nsAString
& aSourceType
)
454 // Only allow for the first source of the first tuner.
456 mTuners
[0]->GetId(tunerId
);
457 if (!aTunerId
.Equals(tunerId
)) {
461 uint32_t sourceTypeCount
;
463 mTuners
[0]->GetSupportedSourceTypes(&sourceTypeCount
, &sourceTypes
);
465 sourceType
.AssignASCII(sourceTypes
[0]);
466 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(sourceTypeCount
, sourceTypes
);
467 if (!aSourceType
.Equals(sourceType
)) {
474 already_AddRefed
<nsITVTunerData
>
475 FakeTVService::MockTuner(const nsAString
& aId
,
476 uint32_t aSupportedSourceTypeCount
,
477 const char** aSupportedSourceTypes
)
479 nsCOMPtr
<nsITVTunerData
> tunerData
= new TVTunerData();
480 tunerData
->SetId(aId
);
481 tunerData
->SetSupportedSourceTypes(aSupportedSourceTypeCount
, aSupportedSourceTypes
);
482 return tunerData
.forget();
485 already_AddRefed
<nsITVChannelData
>
486 FakeTVService::MockChannel(const nsAString
& aNetworkId
,
487 const nsAString
& aTransportStreamId
,
488 const nsAString
& aServiceId
,
489 const nsAString
& aType
,
490 const nsAString
& aNumber
,
491 const nsAString
& aName
,
495 nsCOMPtr
<nsITVChannelData
> channelData
= new TVChannelData();
496 channelData
->SetNetworkId(aNetworkId
);
497 channelData
->SetTransportStreamId(aTransportStreamId
);
498 channelData
->SetServiceId(aServiceId
);
499 channelData
->SetType(aType
);
500 channelData
->SetNumber(aNumber
);
501 channelData
->SetName(aName
);
502 channelData
->SetIsEmergency(aIsEmergency
);
503 channelData
->SetIsFree(aIsFree
);
504 return channelData
.forget();
507 already_AddRefed
<nsITVProgramData
>
508 FakeTVService::MockProgram(const nsAString
& aEventId
,
509 const nsAString
& aTitle
,
512 const nsAString
& aDescription
,
513 const nsAString
& aRating
,
514 uint32_t aAudioLanguageCount
,
515 const char** aAudioLanguages
,
516 uint32_t aSubtitleLanguageCount
,
517 const char** aSubtitleLanguages
)
519 nsCOMPtr
<nsITVProgramData
> programData
= new TVProgramData();
520 programData
->SetEventId(aEventId
);
521 programData
->SetTitle(aTitle
);
522 programData
->SetStartTime(aStartTime
);
523 programData
->SetDuration(aDuration
);
524 programData
->SetDescription(aDescription
);
525 programData
->SetRating(aRating
);
526 programData
->SetAudioLanguages(aAudioLanguageCount
, aAudioLanguages
);
527 programData
->SetSubtitleLanguages(aSubtitleLanguageCount
, aSubtitleLanguages
);
528 return programData
.forget();
532 } // namespace mozilla