--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -178,16 +178,17 @@
#include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
#include "mozilla/dom/PFileSystemRequestChild.h"
#include "mozilla/dom/FileSystemTaskBase.h"
#include "mozilla/dom/bluetooth/PBluetoothChild.h"
#include "mozilla/dom/PFMRadioChild.h"
#include "mozilla/dom/PPresentationChild.h"
#include "mozilla/dom/PresentationIPCService.h"
#include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/dom/PTVChild.h"
#ifdef MOZ_WEBSPEECH
#include "mozilla/dom/PSpeechSynthesisChild.h"
#endif
#include "ProcessUtils.h"
#include "URIUtils.h"
#include "nsContentUtils.h"
@@ -1700,16 +1701,30 @@ ContentChild::RecvNotifyPresentationRece
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
NS_WARN_IF(!service);
NS_WARN_IF(NS_FAILED(service->UntrackSessionInfo(aSessionId)));
return true;
}
+PTVChild*
+ContentChild::AllocPTVChild()
+{
+ NS_NOTREACHED("We should never be manually allocating PTVChild actors");
+ return nullptr;
+}
+
+bool
+ContentChild::DeallocPTVChild(PTVChild* aActor)
+{
+ delete aActor;
+ return true;
+}
+
bool
ContentChild::RecvNotifyGMPsChanged()
{
GMPDecoderModule::UpdateUsableCodecs();
return true;
}
PCrashReporterChild*
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -370,16 +370,20 @@ public:
virtual bool
RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe,
const nsString& aSessionId) override;
virtual bool
RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId) override;
+ virtual PTVChild* AllocPTVChild() override;
+
+ virtual bool DeallocPTVChild(PTVChild* aActor) override;
+
virtual bool RecvNotifyGMPsChanged() override;
virtual PSpeechSynthesisChild* AllocPSpeechSynthesisChild() override;
virtual bool DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor) override;
virtual bool RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
InfallibleTArray<SubstitutionMapping>&& resources,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -68,16 +68,17 @@
#include "mozilla/dom/mobilemessage/SmsParent.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/dom/Permissions.h"
#include "mozilla/dom/PresentationParent.h"
#include "mozilla/dom/PPresentationParent.h"
#include "mozilla/dom/quota/QuotaManagerService.h"
#include "mozilla/dom/telephony/TelephonyParent.h"
#include "mozilla/dom/time/DateCacheCleaner.h"
+#include "mozilla/dom/TVParent.h"
#include "mozilla/dom/voicemail/VoicemailParent.h"
#include "mozilla/embedding/printingui/PrintingParent.h"
#include "mozilla/hal_sandbox/PHalParent.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/FileDescriptorSetParent.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/ipc/PFileDescriptorSetParent.h"
@@ -4144,16 +4145,36 @@ ContentParent::DeallocPPresentationParen
}
bool
ContentParent::RecvPPresentationConstructor(PPresentationParent* aActor)
{
return static_cast<PresentationParent*>(aActor)->Init();
}
+PTVParent*
+ContentParent::AllocPTVParent()
+{
+ RefPtr<TVParent> actor = new TVParent();
+ return actor.forget().take();
+}
+
+bool
+ContentParent::DeallocPTVParent(PTVParent* aActor)
+{
+ RefPtr<TVParent> actor = dont_AddRef(static_cast<TVParent*>(aActor));
+ return true;
+}
+
+bool
+ContentParent::RecvPTVConstructor(PTVParent* aActor)
+{
+ return static_cast<TVParent*>(aActor)->Init();
+}
+
PSpeechSynthesisParent*
ContentParent::AllocPSpeechSynthesisParent()
{
#ifdef MOZ_WEBSPEECH
return new mozilla::dom::SpeechSynthesisParent();
#else
return nullptr;
#endif
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -853,16 +853,22 @@ private:
virtual bool DeallocPFMRadioParent(PFMRadioParent* aActor) override;
virtual PPresentationParent* AllocPPresentationParent() override;
virtual bool DeallocPPresentationParent(PPresentationParent* aActor) override;
virtual bool RecvPPresentationConstructor(PPresentationParent* aActor) override;
+ virtual PTVParent* AllocPTVParent() override;
+
+ virtual bool DeallocPTVParent(PTVParent* aActor) override;
+
+ virtual bool RecvPTVConstructor(PTVParent* aActor) override;
+
virtual PSpeechSynthesisParent* AllocPSpeechSynthesisParent() override;
virtual bool
DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* aActor) override;
virtual bool
RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor) override;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -51,16 +51,17 @@ include protocol PTelephony;
include protocol PTestShell;
include protocol PVoicemail;
include protocol PJavaScript;
include protocol PRemoteSpellcheckEngine;
include protocol PWebBrowserPersistDocument;
include protocol PWebrtcGlobal;
include protocol PPresentation;
include protocol PVRManager;
+include protocol PTV;
include DOMTypes;
include JavaScriptTypes;
include InputStreamParams;
include PTabContext;
include URIParams;
include PluginTypes;
include ProtocolTypes;
include PBackgroundSharedTypes;
@@ -500,16 +501,17 @@ prio(normal upto urgent) sync protocol P
manages PTelephony;
manages PTestShell;
manages PVoicemail;
manages PJavaScript;
manages PRemoteSpellcheckEngine;
manages PWebBrowserPersistDocument;
manages PWebrtcGlobal;
manages PPresentation;
+ manages PTV;
both:
// Depending on exactly how the new browser is being created, it might be
// created from either the child or parent process!
//
// The child creates the PBrowser as part of
// TabChild::BrowserFrameProvideWindow (which happens when the child's
// content calls window.open()), and the parent creates the PBrowser as part
@@ -880,16 +882,18 @@ parent:
async PBluetooth();
async PFMRadio();
async PWebrtcGlobal();
async PPresentation();
+ async PTV();
+
// Services remoting
async StartVisitedQuery(URIParams uri);
async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags);
async SetURITitle(URIParams uri, nsString title);
async LoadURIExternal(URIParams uri, PBrowser windowContext);
--- a/dom/tv/TVServiceFactory.cpp
+++ b/dom/tv/TVServiceFactory.cpp
@@ -1,14 +1,15 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/. */
+#include "ipc/TVIPCService.h"
#include "nsITVService.h"
#include "nsITVSimulatorService.h"
#include "nsServiceManagerUtils.h"
#include "TVServiceFactory.h"
#ifdef MOZ_WIDGET_GONK
#include "gonk/TVGonkService.h"
#endif
@@ -16,16 +17,21 @@
namespace mozilla {
namespace dom {
/* static */ already_AddRefed<nsITVService>
TVServiceFactory::AutoCreateTVService()
{
nsCOMPtr<nsITVService> service;
+ if (GeckoProcessType_Default != XRE_GetProcessType()) {
+ service = new TVIPCService();
+ return service.forget();
+ }
+
#ifdef MOZ_WIDGET_GONK
service = new TVGonkService();
#endif
if (service == nullptr) {
// Fallback to TV simulator service, especially for TV simulator on WebIDE.
service = do_CreateInstance(TV_SIMULATOR_SERVICE_CONTRACTID);
}
--- a/dom/tv/TVTypes.cpp
+++ b/dom/tv/TVTypes.cpp
@@ -76,18 +76,32 @@ TVTunerData::GetSupportedSourceTypes(uin
sourceTypes[i] = NS_strdup(mSupportedSourceTypes[i]);
}
*aSourceTypes = sourceTypes;
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
-TVTunerData::SetSupportedSourceTypes(uint32_t aCount,
- const char** aSourceTypes)
+TVTunerData::GetSupportedSourceTypesByString(uint32_t* aCount,
+ nsTArray<nsCString>& aSourceTypes)
+{
+ *aCount = mCount;
+
+ for (uint32_t i = 0; i < mCount; i++) {
+ nsCString sourceType;
+ sourceType.AssignASCII(mSupportedSourceTypes[i]);
+ aSourceTypes.AppendElement(sourceType);
+ }
+
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVTunerData::SetSupportedSourceTypes(uint32_t aCount, const char** aSourceTypes)
{
if (aCount == 0) {
return NS_ERROR_INVALID_ARG;
}
NS_ENSURE_ARG_POINTER(aSourceTypes);
for (uint32_t i = 0; i < aCount; i++) {
if (TVSourceType::EndGuard_ == ToTVSourceType(aSourceTypes[i])) {
@@ -106,16 +120,47 @@ TVTunerData::SetSupportedSourceTypes(uin
nullptr;
for (uint32_t i = 0; i < mCount; i++) {
mSupportedSourceTypes[i] = NS_strdup(aSourceTypes[i]);
}
return NS_OK;
}
+/* virtual */ NS_IMETHODIMP
+TVTunerData::SetSupportedSourceTypesByString(
+ uint32_t aCount, const nsTArray<nsCString>& aSourceTypes)
+{
+ if (aCount == 0) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ for (uint32_t i = 0; i < aCount; i++) {
+ if (TVSourceType::EndGuard_ ==
+ ToTVSourceType(NS_ConvertUTF8toUTF16(aSourceTypes[i]))) {
+
+ return NS_ERROR_INVALID_ARG;
+ }
+ }
+
+ if (mSupportedSourceTypes) {
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mSupportedSourceTypes);
+ }
+
+ mCount = aCount;
+
+ mSupportedSourceTypes =
+ (mCount > 0) ? static_cast<char**>(moz_xmalloc(mCount * sizeof(char*)))
+ : nullptr;
+ for (uint32_t i = 0; i < mCount; i++) {
+ mSupportedSourceTypes[i] = NS_strdup(aSourceTypes[i].get());
+ }
+
+ return NS_OK;
+}
/*
* Implementation of TVChannelData
*/
NS_IMPL_ISUPPORTS(TVChannelData, nsITVChannelData)
TVChannelData::TVChannelData()
@@ -400,18 +445,32 @@ TVProgramData::GetAudioLanguages(uint32_
languages[i] = NS_strdup(mAudioLanguages[i]);
}
*aLanguages = languages;
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
-TVProgramData::SetAudioLanguages(uint32_t aCount,
- const char** aLanguages)
+TVProgramData::GetAudioLanguagesByString(uint32_t* aCount,
+ nsTArray<nsCString>& aLanguages)
+{
+ *aCount = mAudioLanguageCount;
+
+ for (uint32_t i = 0; i < mAudioLanguageCount; i++) {
+ nsCString languages;
+ languages.AssignASCII(mAudioLanguages[i]);
+ aLanguages.AppendElement(languages);
+ }
+
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVProgramData::SetAudioLanguages(uint32_t aCount, const char** aLanguages)
{
if (aCount > 0) {
NS_ENSURE_ARG_POINTER(aLanguages);
}
if (mAudioLanguages) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mAudioLanguageCount, mAudioLanguages);
}
@@ -424,56 +483,108 @@ TVProgramData::SetAudioLanguages(uint32_
for (uint32_t i = 0; i < mAudioLanguageCount; i++) {
mAudioLanguages[i] = NS_strdup(aLanguages[i]);
}
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
-TVProgramData::GetSubtitleLanguages(uint32_t* aCount,
- char*** aLanguages)
+TVProgramData::SetAudioLanguagesByString(uint32_t aCount,
+ const nsTArray<nsCString>& aLanguages)
+{
+ if (mAudioLanguages) {
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mAudioLanguageCount, mAudioLanguages);
+ }
+
+ mAudioLanguageCount = aCount;
+
+ mAudioLanguages =
+ (mAudioLanguageCount > 0)
+ ? static_cast<char**>(moz_xmalloc(mAudioLanguageCount * sizeof(char*)))
+ : nullptr;
+ for (uint32_t i = 0; i < mAudioLanguageCount; i++) {
+ mAudioLanguages[i] = NS_strdup(aLanguages[i].get());
+ }
+
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVProgramData::GetSubtitleLanguages(uint32_t* aCount, char*** aLanguages)
{
*aCount = mSubtitleLanguageCount;
char** languages = (mSubtitleLanguageCount > 0) ?
static_cast<char **>(moz_xmalloc(mSubtitleLanguageCount * sizeof(char*))) :
nullptr;
for (uint32_t i = 0; i < mSubtitleLanguageCount; i++) {
languages[i] = NS_strdup(mSubtitleLanguages[i]);
}
*aLanguages = languages;
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
-TVProgramData::SetSubtitleLanguages(uint32_t aCount,
- const char** aLanguages)
+TVProgramData::GetSubtitleLanguagesByString(uint32_t* aCount,
+ nsTArray<nsCString>& aLanguages)
{
- if (aCount > 0) {
- NS_ENSURE_ARG_POINTER(aLanguages);
+ *aCount = mSubtitleLanguageCount;
+
+ for (uint32_t i = 0; i < mSubtitleLanguageCount; i++) {
+ nsCString languages;
+ languages.AssignASCII(mSubtitleLanguages[i]);
+ aLanguages.AppendElement(languages);
}
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVProgramData::SetSubtitleLanguages(uint32_t aCount, const char** aLanguages)
+{
if (mSubtitleLanguages) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mSubtitleLanguageCount, mSubtitleLanguages);
}
mSubtitleLanguageCount = aCount;
mSubtitleLanguages = (mSubtitleLanguageCount > 0) ?
static_cast<char **>(moz_xmalloc(mSubtitleLanguageCount * sizeof(char*))) :
nullptr;
for (uint32_t i = 0; i < mSubtitleLanguageCount; i++) {
mSubtitleLanguages[i] = NS_strdup(aLanguages[i]);
}
return NS_OK;
}
+/* virtual */ NS_IMETHODIMP
+TVProgramData::SetSubtitleLanguagesByString(
+ uint32_t aCount, const nsTArray<nsCString>& aLanguages)
+{
+ if (mSubtitleLanguages) {
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mSubtitleLanguageCount,
+ mSubtitleLanguages);
+ }
+
+ mSubtitleLanguageCount = aCount;
+
+ mSubtitleLanguages =
+ (mSubtitleLanguageCount > 0)
+ ? static_cast<char**>(moz_xmalloc(mSubtitleLanguageCount * sizeof(char*)))
+ : nullptr;
+ for (uint32_t i = 0; i < mSubtitleLanguageCount; i++) {
+ mSubtitleLanguages[i] = NS_strdup(aLanguages[i].get());
+ }
+
+ return NS_OK;
+}
+
/*
* Implementation of TVGonkNativeHandleData
*/
NS_IMPL_ISUPPORTS(TVGonkNativeHandleData, nsITVGonkNativeHandleData)
TVGonkNativeHandleData::TVGonkNativeHandleData() {}
--- a/dom/tv/TVTypes.h
+++ b/dom/tv/TVTypes.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TVTypes_h
#define mozilla_dom_TVTypes_h
#include "mozilla/layers/GonkNativeHandle.h"
#include "mozilla/Tuple.h"
#include "nsITVService.h"
+#include "mozilla/dom/PTVTypes.h"
namespace mozilla {
namespace dom {
typedef Tuple<nsString, nsString, nsCOMPtr<nsITVSourceListener>>
TVSourceListenerTuple;
using mozilla::layers::GonkNativeHandle;
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/PTV.ipdl
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* 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/. */
+
+include protocol PContent;
+include protocol PTVRequest;
+include PTVTypes;
+
+namespace mozilla {
+namespace dom {
+
+struct TVGetTunersRequest {
+};
+
+struct TVSetSourceRequest {
+ nsString tunerId;
+ nsString sourceType;
+};
+
+struct TVStartScanningChannelsRequest {
+ nsString tunerId;
+ nsString sourceType;
+};
+
+struct TVStopScanningChannelsRequest {
+ nsString tunerId;
+ nsString sourceType;
+};
+
+struct TVClearScannedChannelsCacheRequest {
+};
+
+struct TVSetChannelRequest {
+ nsString tunerId;
+ nsString sourceType;
+ nsString channelNumber;
+};
+
+struct TVGetChannelsRequest {
+ nsString tunerId;
+ nsString sourceType;
+};
+
+struct TVGetProgramsRequest {
+ nsString tunerId;
+ nsString sourceType;
+ nsString channelNumber;
+ uint64_t startTime;
+ uint64_t endTime;
+};
+
+union TVIPCRequest {
+ TVGetTunersRequest;
+ TVSetSourceRequest;
+ TVStartScanningChannelsRequest;
+ TVStopScanningChannelsRequest;
+ TVClearScannedChannelsCacheRequest;
+ TVSetChannelRequest;
+ TVGetChannelsRequest;
+ TVGetProgramsRequest;
+};
+
+protocol PTV {
+ manager PContent;
+ manages PTVRequest;
+
+child:
+ async NotifyChannelScanned(nsString tunerId, nsString sourceType,
+ TVIPCChannelData channelData);
+ async NotifyChannelScanComplete(nsString tunerId, nsString sourceType);
+ async NotifyChannelScanStopped(nsString tunerId, nsString sourceType);
+ async NotifyEITBroadcasted(nsString tunerId, nsString sourceType,
+ TVIPCChannelData channelData,
+ TVIPCProgramData[] programData);
+
+parent:
+ async __delete__();
+
+ async PTVRequest(TVIPCRequest aRequest);
+
+ async RegisterSourceHandler(nsString tunerId, nsString sourceType);
+ async UnregisterSourceHandler(nsString tunerId, nsString sourceType);
+};
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/PTVRequest.ipdl
@@ -0,0 +1,60 @@
+/* -*- 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/. */
+
+include protocol PTV;
+include PTVTypes;
+
+namespace mozilla {
+namespace dom {
+
+
+struct TVSuccessResponse {
+};
+
+struct TVErrorResponse {
+ uint16_t errorCode;
+};
+
+struct TVGetTunersResponse {
+ TVIPCTunerData[] tuners;
+};
+
+struct TVSetSourceResponse {
+ TVIPCGonkNativeHandleData streamHandle;
+};
+
+struct TVSetChannelResponse {
+ TVIPCChannelData channel;
+};
+
+struct TVGetChannelsResponse {
+ TVIPCChannelData[] channels;
+};
+
+struct TVGetProgramsResponse {
+ TVIPCProgramData[] programs;
+};
+
+union TVIPCResponse {
+ TVSuccessResponse;
+ TVErrorResponse;
+ TVGetTunersResponse;
+ TVSetSourceResponse;
+ TVSetChannelResponse;
+ TVGetChannelsResponse;
+ TVGetProgramsResponse;
+};
+
+protocol PTVRequest
+{
+ manager PTV;
+
+child:
+ async __delete__(TVIPCResponse aResponse);
+};
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/PTVTypes.ipdlh
@@ -0,0 +1,42 @@
+using struct mozilla::layers::GonkNativeHandle from "mozilla/layers/GonkNativeHandleUtils.h";
+
+namespace mozilla {
+namespace dom {
+
+struct TVIPCTunerData {
+ nsString id;
+ uint16_t streamType;
+ uint32_t sourceTypeCount;
+ nsCString[] sourceTypes;
+};
+
+struct TVIPCChannelData {
+ nsCString networkId;
+ nsCString transportStreamId;
+ nsCString serviceId;
+ nsCString type;
+ nsCString number;
+ nsCString name;
+ bool isEmergency;
+ bool isFree;
+};
+
+struct TVIPCProgramData {
+ nsCString eventId;
+ nsCString title;
+ uint64_t startTime;
+ uint64_t duration;
+ nsCString description;
+ nsCString rating;
+ uint32_t audioLanguageCount;
+ nsCString[] audioLanguages;
+ uint32_t subtitleLanguageCount;
+ nsCString[] subtitleLanguages;
+};
+
+struct TVIPCGonkNativeHandleData {
+ GonkNativeHandle handle;
+};
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVChild.cpp
@@ -0,0 +1,323 @@
+/* -*- 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/. */
+
+#include "nsIMutableArray.h"
+#include "TVChild.h"
+#include "TVTuner.h"
+#include "TVIPCService.h"
+#include "TVIPCHelper.h"
+#include "TVServiceRunnables.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+/*
+ * Implementation of TVChild
+ */
+
+TVChild::TVChild(TVIPCService* aService)
+ : mActorDestroyed(false), mService(aService)
+{
+ MOZ_ASSERT(mService);
+
+ MOZ_COUNT_CTOR(TVChild);
+}
+
+TVChild::~TVChild()
+{
+ MOZ_COUNT_DTOR(TVChild);
+
+ if (!mActorDestroyed) {
+ Send__delete__(this);
+ }
+ mService = nullptr;
+}
+
+/* virtual */ void
+TVChild::ActorDestroy(ActorDestroyReason aWhy)
+{
+ mActorDestroyed = true;
+ mService = nullptr;
+}
+
+/* virtual */ PTVRequestChild*
+TVChild::AllocPTVRequestChild(const TVIPCRequest& aRequest)
+{
+ NS_NOTREACHED(
+ "We should never be manually allocating PTVRequestChild actors");
+ return nullptr;
+}
+
+/* virtual */ bool
+TVChild::DeallocPTVRequestChild(PTVRequestChild* aActor)
+{
+ delete aActor;
+ return true;
+}
+
+/* virtual */ bool
+TVChild::RecvNotifyChannelScanned(const nsString& aTunerId,
+ const nsString& aSourceType,
+ const TVIPCChannelData& aChannelData)
+{
+ if (mService) {
+ nsCOMPtr<nsITVChannelData> channelData;
+ channelData = do_CreateInstance(TV_CHANNEL_DATA_CONTRACTID);
+ UnpackTVIPCChannelData(channelData, aChannelData);
+ NS_WARN_IF(NS_FAILED(
+ mService->NotifyChannelScanned(aTunerId, aSourceType, channelData)));
+ }
+ return true;
+}
+
+/* virtual */ bool
+TVChild::RecvNotifyChannelScanComplete(const nsString& aTunerId,
+ const nsString& aSourceType)
+{
+ if (mService) {
+ NS_WARN_IF(
+ NS_FAILED(mService->NotifyChannelScanComplete(aTunerId, aSourceType)));
+ }
+ return true;
+}
+
+/* virtual */ bool
+TVChild::RecvNotifyChannelScanStopped(const nsString& aTunerId,
+ const nsString& aSourceType)
+{
+ if (mService) {
+ NS_WARN_IF(
+ NS_FAILED(mService->NotifyChannelScanStopped(aTunerId, aSourceType)));
+ }
+ return true;
+}
+
+/* virtual */ bool
+TVChild::RecvNotifyEITBroadcasted(const nsString& aTunerId,
+ const nsString& aSourceType,
+ const TVIPCChannelData& aChannelData,
+ nsTArray<TVIPCProgramData>&& aProgramDataList)
+{
+ if (mService) {
+ nsCOMPtr<nsITVChannelData> channelData;
+ channelData = do_CreateInstance(TV_CHANNEL_DATA_CONTRACTID);
+ UnpackTVIPCChannelData(channelData, aChannelData);
+
+ uint32_t count = aProgramDataList.Length();
+ nsTArray<nsITVProgramData*> programDataList(count);
+ for (uint32_t i = 0; i < count; i++) {
+ nsCOMPtr<nsITVProgramData> programData;
+ programData = do_CreateInstance(TV_PROGRAM_DATA_CONTRACTID);
+ UnpackTVIPCProgramData(programData, aProgramDataList[i]);
+ programDataList.AppendElement(programData);
+ }
+
+ nsresult rv = mService->NotifyEITBroadcasted(
+ aTunerId, aSourceType, channelData, programDataList.Elements(), count);
+ NS_WARN_IF(NS_FAILED(rv));
+ }
+ return true;
+}
+
+/*
+ * Implementation of TVRequestChild
+ */
+
+TVRequestChild::TVRequestChild(nsITVServiceCallback* aCallback)
+ : mActorDestroyed(false), mCallback(aCallback)
+{
+ MOZ_COUNT_CTOR(TVRequestChild);
+}
+
+TVRequestChild::~TVRequestChild()
+{
+ MOZ_COUNT_DTOR(TVRequestChild);
+
+ mCallback = nullptr;
+}
+
+/* virtual */ void
+TVRequestChild::ActorDestroy(ActorDestroyReason aWhy)
+{
+ mActorDestroyed = true;
+ mCallback = nullptr;
+}
+
+/* virtual */ bool
+TVRequestChild::Recv__delete__(const TVIPCResponse& aResponse)
+{
+ if (mActorDestroyed) {
+ return true;
+ }
+
+ if (!mCallback) {
+ return true;
+ }
+
+ nsresult rv = NS_ERROR_FAILURE;
+ switch (aResponse.type()) {
+ case TVIPCResponse::TTVSuccessResponse:
+ rv = DoResponse(aResponse.get_TVSuccessResponse());
+ break;
+ case TVIPCResponse::TTVErrorResponse:
+ rv = DoResponse(aResponse.get_TVErrorResponse());
+ break;
+ case TVIPCResponse::TTVGetTunersResponse:
+ rv = DoResponse(aResponse.get_TVGetTunersResponse());
+ break;
+ case TVIPCResponse::TTVSetSourceResponse:
+ rv = DoResponse(aResponse.get_TVSetSourceResponse());
+ break;
+ case TVIPCResponse::TTVSetChannelResponse:
+ rv = DoResponse(aResponse.get_TVSetChannelResponse());
+ break;
+ case TVIPCResponse::TTVGetChannelsResponse:
+ rv = DoResponse(aResponse.get_TVGetChannelsResponse());
+ break;
+ case TVIPCResponse::TTVGetProgramsResponse:
+ rv = DoResponse(aResponse.get_TVGetProgramsResponse());
+ break;
+ default:
+ MOZ_CRASH("Unknown TVIPCResponse type");
+ }
+
+ return NS_WARN_IF(NS_FAILED(rv)) ? false : true;
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVSuccessResponse& aResponse)
+{
+ if (mCallback) {
+ return mCallback->NotifySuccess(nullptr);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVErrorResponse& aResponse)
+{
+ if (mCallback) {
+ return mCallback->NotifyError(aResponse.errorCode());
+ }
+
+ return NS_OK;
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVGetTunersResponse& aResponse)
+{
+ MOZ_ASSERT(mCallback);
+
+ nsCOMPtr<nsIMutableArray> tunerDataList =
+ do_CreateInstance(NS_ARRAY_CONTRACTID);
+ if (!tunerDataList) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ const nsTArray<TVIPCTunerData>& tuners = aResponse.tuners();
+ for (uint32_t i = 0; i < tuners.Length(); i++) {
+ nsCOMPtr<nsITVTunerData> tunerData;
+ tunerData = do_CreateInstance(TV_TUNER_DATA_CONTRACTID);
+ UnpackTVIPCTunerData(tunerData, tuners[i]);
+ tunerDataList->AppendElement(tunerData, false);
+ }
+
+ nsCOMPtr<nsIRunnable> runnable =
+ new TVServiceNotifyRunnable(mCallback, tunerDataList);
+ return NS_DispatchToCurrentThread(runnable);
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVSetSourceResponse& aResponse)
+{
+ MOZ_ASSERT(mCallback);
+
+ nsCOMPtr<nsIMutableArray> handleDataList =
+ do_CreateInstance(NS_ARRAY_CONTRACTID);
+ if (!handleDataList) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ nsCOMPtr<nsITVGonkNativeHandleData> handleData;
+ handleData = do_CreateInstance(TV_GONK_NATIVE_HANDLE_DATA_CONTRACTID);
+ UnpackTVIPCGonkNativeHandleData(handleData, aResponse.streamHandle());
+ handleDataList->AppendElement(handleData, false);
+
+ nsCOMPtr<nsIRunnable> runnable =
+ new TVServiceNotifyRunnable(mCallback, handleDataList);
+ return NS_DispatchToCurrentThread(runnable);
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVSetChannelResponse& aResponse)
+{
+ MOZ_ASSERT(mCallback);
+
+ nsCOMPtr<nsIMutableArray> channelDataList =
+ do_CreateInstance(NS_ARRAY_CONTRACTID);
+ if (!channelDataList) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ nsCOMPtr<nsITVChannelData> channelData;
+ channelData = do_CreateInstance(TV_CHANNEL_DATA_CONTRACTID);
+ UnpackTVIPCChannelData(channelData, aResponse.channel());
+ channelDataList->AppendElement(channelData, false);
+
+ nsCOMPtr<nsIRunnable> runnable =
+ new TVServiceNotifyRunnable(mCallback, channelDataList);
+ return NS_DispatchToCurrentThread(runnable);
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVGetChannelsResponse& aResponse)
+{
+ MOZ_ASSERT(mCallback);
+
+ nsCOMPtr<nsIMutableArray> channelDataList =
+ do_CreateInstance(NS_ARRAY_CONTRACTID);
+ if (!channelDataList) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ const nsTArray<TVIPCChannelData>& channels = aResponse.channels();
+ for (uint32_t i = 0; i < channels.Length(); i++) {
+ nsCOMPtr<nsITVChannelData> channelData;
+ channelData = do_CreateInstance(TV_CHANNEL_DATA_CONTRACTID);
+ UnpackTVIPCChannelData(channelData, channels[i]);
+
+ channelDataList->AppendElement(channelData, false);
+ }
+
+ nsCOMPtr<nsIRunnable> runnable =
+ new TVServiceNotifyRunnable(mCallback, channelDataList);
+ return NS_DispatchToCurrentThread(runnable);
+}
+
+nsresult
+TVRequestChild::DoResponse(const TVGetProgramsResponse& aResponse)
+{
+ MOZ_ASSERT(mCallback);
+
+ nsCOMPtr<nsIMutableArray> programDataList =
+ do_CreateInstance(NS_ARRAY_CONTRACTID);
+ if (!programDataList) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ const nsTArray<TVIPCProgramData>& programs = aResponse.programs();
+ for (uint32_t i = 0; i < programs.Length(); i++) {
+ nsCOMPtr<nsITVProgramData> programData;
+ programData = do_CreateInstance(TV_PROGRAM_DATA_CONTRACTID);
+ UnpackTVIPCProgramData(programData, programs[i]);
+ programDataList->AppendElement(programData, false);
+ }
+
+ nsCOMPtr<nsIRunnable> runnable =
+ new TVServiceNotifyRunnable(mCallback, programDataList);
+ return NS_DispatchToCurrentThread(runnable);
+}
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVChild.h
@@ -0,0 +1,88 @@
+/* -*- 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_TVChild_h
+#define mozilla_dom_TVChild_h
+
+#include "mozilla/dom/PTVChild.h"
+#include "mozilla/dom/PTVRequestChild.h"
+#include "mozilla/dom/PTVTypes.h"
+
+class nsITVServiceCallback;
+
+namespace mozilla {
+namespace dom {
+
+class TVIPCService;
+
+class TVChild final : public PTVChild
+{
+public:
+ explicit TVChild(TVIPCService* aService);
+
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ virtual PTVRequestChild* AllocPTVRequestChild(const TVIPCRequest& aRequest)
+ override;
+
+ virtual bool DeallocPTVRequestChild(PTVRequestChild* aActor) override;
+
+ virtual bool RecvNotifyChannelScanned(
+ const nsString& aTunerId, const nsString& aSourceType,
+ const TVIPCChannelData& aChannelData) override;
+
+ virtual bool RecvNotifyChannelScanComplete(
+ const nsString& aTunerId, const nsString& aSourceType) override;
+
+ virtual bool RecvNotifyChannelScanStopped(
+ const nsString& aTunerId, const nsString& aSourceType) override;
+
+ virtual bool RecvNotifyEITBroadcasted(
+ const nsString& aTunerId, const nsString& aSourceType,
+ const TVIPCChannelData& aChannelData,
+ nsTArray<TVIPCProgramData>&& aProgramDataList) override;
+
+private:
+ ~TVChild();
+
+ bool mActorDestroyed;
+ RefPtr<TVIPCService> mService;
+};
+
+class TVRequestChild final : public PTVRequestChild
+{
+public:
+ explicit TVRequestChild(nsITVServiceCallback* aCallback);
+
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ virtual bool Recv__delete__(const TVIPCResponse& aResponse) override;
+
+private:
+ virtual ~TVRequestChild();
+
+ nsresult DoResponse(const TVSuccessResponse& aResponse);
+
+ nsresult DoResponse(const TVErrorResponse& aResponse);
+
+ nsresult DoResponse(const TVGetTunersResponse& aResponse);
+
+ nsresult DoResponse(const TVSetSourceResponse& aResponse);
+
+ nsresult DoResponse(const TVSetChannelResponse& aResponse);
+
+ nsresult DoResponse(const TVGetChannelsResponse& aResponse);
+
+ nsresult DoResponse(const TVGetProgramsResponse& aResponse);
+
+ bool mActorDestroyed;
+ nsCOMPtr<nsITVServiceCallback> mCallback;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TVChild_h
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVIPCHelper.cpp
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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/. */
+
+#include "TVIPCHelper.h"
+#include "nsITVService.h"
+#include "mozilla/dom/PTVTypes.h"
+
+namespace mozilla {
+namespace dom {
+
+/*
+ * TVTunerData Pack/Unpack.
+ */
+void
+PackTVIPCTunerData(nsITVTunerData* aTunerData, TVIPCTunerData& aIPCTunerData)
+{
+ nsAutoString id;
+ uint16_t streamType;
+ uint32_t sourceTypeCount;
+ nsTArray<nsCString> sourceTypes;
+
+ if (aTunerData == nullptr) {
+ return;
+ }
+
+ aTunerData->GetId(aIPCTunerData.id());
+ aTunerData->GetStreamType(&streamType);
+ aIPCTunerData.streamType() = streamType;
+ aTunerData->GetSupportedSourceTypesByString(&sourceTypeCount, sourceTypes);
+ aIPCTunerData.sourceTypeCount() = sourceTypeCount;
+ aIPCTunerData.sourceTypes() = sourceTypes;
+ return;
+}
+
+void
+UnpackTVIPCTunerData(nsITVTunerData* aTunerData,
+ const TVIPCTunerData& aIPCTunerData)
+{
+ if (aTunerData == nullptr) {
+ return;
+ }
+
+ aTunerData->SetId(aIPCTunerData.id());
+ aTunerData->SetStreamType(aIPCTunerData.streamType());
+ aTunerData->SetSupportedSourceTypesByString(aIPCTunerData.sourceTypeCount(),
+ aIPCTunerData.sourceTypes());
+ return;
+}
+
+/*
+ * TVChannelData Pack/Unpack.
+ */
+void
+PackTVIPCChannelData(nsITVChannelData* aChannelData,
+ TVIPCChannelData& aIPCChannelData)
+{
+ nsString networkId;
+ nsString transportStreamId;
+ nsString serviceId;
+ nsString type;
+ nsString number;
+ nsString name;
+
+ if (aChannelData == nullptr) {
+ return;
+ }
+
+ aChannelData->GetNetworkId(networkId);
+ aIPCChannelData.networkId() = NS_ConvertUTF16toUTF8(networkId);
+ aChannelData->GetTransportStreamId(transportStreamId);
+ aIPCChannelData.transportStreamId() =
+ NS_ConvertUTF16toUTF8(transportStreamId);
+ aChannelData->GetServiceId(serviceId);
+ aIPCChannelData.serviceId() = NS_ConvertUTF16toUTF8(serviceId);
+ aChannelData->GetType(type);
+ aIPCChannelData.type() = NS_ConvertUTF16toUTF8(type);
+ aChannelData->GetNumber(number);
+ aIPCChannelData.number() = NS_ConvertUTF16toUTF8(number);
+ aChannelData->GetName(name);
+ aIPCChannelData.name() = NS_ConvertUTF16toUTF8(name);
+ aChannelData->GetIsEmergency(&aIPCChannelData.isEmergency());
+ aChannelData->GetIsFree(&aIPCChannelData.isFree());
+ return;
+}
+
+void
+UnpackTVIPCChannelData(nsITVChannelData* aChannelData,
+ const TVIPCChannelData& aIPCChannelData)
+{
+ if (aChannelData == nullptr) {
+ return;
+ }
+
+ aChannelData->SetNetworkId(
+ NS_ConvertUTF8toUTF16(aIPCChannelData.networkId()));
+ aChannelData->SetTransportStreamId(
+ NS_ConvertUTF8toUTF16(aIPCChannelData.transportStreamId()));
+ aChannelData->SetServiceId(
+ NS_ConvertUTF8toUTF16(aIPCChannelData.serviceId()));
+ aChannelData->SetType(NS_ConvertUTF8toUTF16(aIPCChannelData.type()));
+ aChannelData->SetNumber(NS_ConvertUTF8toUTF16(aIPCChannelData.number()));
+ aChannelData->SetName(NS_ConvertUTF8toUTF16(aIPCChannelData.name()));
+ aChannelData->SetIsEmergency(aIPCChannelData.isEmergency());
+ aChannelData->SetIsFree(aIPCChannelData.isFree());
+
+ return;
+}
+
+/*
+ * TVProgramData Pack/Unpack.
+ */
+void
+PackTVIPCProgramData(nsITVProgramData* aProgramData,
+ TVIPCProgramData& aIPCProgramData)
+{
+ nsString eventId;
+ nsString title;
+ uint64_t startTime;
+ uint64_t duration;
+ nsString description;
+ nsString rating;
+ uint32_t audioLanguageCount;
+ nsTArray<nsCString> audioLanguages;
+ uint32_t subtitleLanguageCount;
+ nsTArray<nsCString> subtitleLanguages;
+
+ if (aProgramData == nullptr) {
+ return;
+ }
+
+ aProgramData->GetEventId(eventId);
+ aIPCProgramData.eventId() = NS_ConvertUTF16toUTF8(eventId);
+
+ aProgramData->GetTitle(title);
+ aIPCProgramData.title() = NS_ConvertUTF16toUTF8(title);
+
+ aProgramData->GetStartTime(&startTime);
+ aIPCProgramData.startTime() = startTime;
+
+ aProgramData->GetDuration(&duration);
+ aIPCProgramData.duration() = duration;
+
+ aProgramData->GetDescription(description);
+ aIPCProgramData.description() = NS_ConvertUTF16toUTF8(description);
+
+ aProgramData->GetRating(rating);
+ aIPCProgramData.rating() = NS_ConvertUTF16toUTF8(rating);
+
+ aProgramData->GetAudioLanguagesByString(&audioLanguageCount, audioLanguages);
+ aIPCProgramData.audioLanguageCount() = audioLanguageCount;
+ aIPCProgramData.audioLanguages() = audioLanguages;
+
+ aProgramData->GetSubtitleLanguagesByString(&subtitleLanguageCount,
+ subtitleLanguages);
+ aIPCProgramData.subtitleLanguageCount() = subtitleLanguageCount;
+ aIPCProgramData.subtitleLanguages() = subtitleLanguages;
+
+ return;
+}
+
+void
+UnpackTVIPCProgramData(nsITVProgramData* aProgramData,
+ const TVIPCProgramData& aIPCProgramData)
+{
+ if (aProgramData == nullptr) {
+ return;
+ }
+
+ aProgramData->SetEventId(NS_ConvertUTF8toUTF16(aIPCProgramData.eventId()));
+ aProgramData->SetTitle(NS_ConvertUTF8toUTF16(aIPCProgramData.title()));
+ aProgramData->SetStartTime(aIPCProgramData.startTime());
+ aProgramData->SetDuration(aIPCProgramData.duration());
+ aProgramData->SetDescription(
+ NS_ConvertUTF8toUTF16(aIPCProgramData.description()));
+ aProgramData->SetRating(NS_ConvertUTF8toUTF16(aIPCProgramData.rating()));
+ aProgramData->SetAudioLanguagesByString(aIPCProgramData.audioLanguageCount(),
+ aIPCProgramData.audioLanguages());
+ aProgramData->SetSubtitleLanguagesByString(
+ aIPCProgramData.subtitleLanguageCount(),
+ aIPCProgramData.subtitleLanguages());
+ return;
+}
+
+/**
+ * nsITVGonkNativeHandleData Serialize/De-serialize.
+ */
+void
+PackTVIPCGonkNativeHandleData(nsITVGonkNativeHandleData* aNativeHandleData,
+ TVIPCGonkNativeHandleData& aIPCNativeHandleData)
+{
+ if (aNativeHandleData == nullptr) {
+ return;
+ }
+
+ aNativeHandleData->SetHandle(aIPCNativeHandleData.handle());
+ return;
+}
+
+void
+UnpackTVIPCGonkNativeHandleData(
+ nsITVGonkNativeHandleData* aNativeHandleData,
+ const TVIPCGonkNativeHandleData& aIPCNativeHandleData)
+{
+ if (aNativeHandleData == nullptr) {
+ return;
+ }
+
+ aNativeHandleData->SetHandle(
+ const_cast<GonkNativeHandle&>(aIPCNativeHandleData.handle()));
+ return;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVIPCHelper.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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_TVIPCHelper_h
+#define mozilla_dom_TVIPCHelper_h
+
+#include "nsITVService.h"
+#include "mozilla/dom/PTVTypes.h"
+
+namespace mozilla {
+namespace dom {
+
+/*
+ * TVTunerData Pack/Unpack.
+ */
+void
+PackTVIPCTunerData(nsITVTunerData* aTunerData, TVIPCTunerData& aIPCTunerData);
+
+void
+UnpackTVIPCTunerData(nsITVTunerData* aTunerData,
+ const TVIPCTunerData& aIPCTunerData);
+
+/*
+ * TVChannelData Pack/Unpack.
+ */
+void
+PackTVIPCChannelData(nsITVChannelData* aChannelData,
+ TVIPCChannelData& aIPCChannelData);
+
+void
+UnpackTVIPCChannelData(nsITVChannelData* aChannelData,
+ const TVIPCChannelData& aIPCChannelData);
+
+/*
+ * TVProgramData Pack/Unpack.
+ */
+void
+PackTVIPCProgramData(nsITVProgramData* aProgramData,
+ TVIPCProgramData& aIPCProgramData);
+
+void
+UnpackTVIPCProgramData(nsITVProgramData* aProgramData,
+ const TVIPCProgramData& aIPCProgramData);
+
+/**
+ * nsITVGonkNativeHandleData Serialize/De-serialize.
+ */
+void
+PackTVIPCGonkNativeHandleData(nsITVGonkNativeHandleData* aNativeHandleData,
+ TVIPCGonkNativeHandleData& aIPCNativeHandleData);
+
+void
+UnpackTVIPCGonkNativeHandleData(
+ nsITVGonkNativeHandleData* aNativeHandleData,
+ const TVIPCGonkNativeHandleData& aIPCNativeHandleData);
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TVIPCHelper_h
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVIPCService.cpp
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* 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/. */
+
+#include "mozilla/dom/ContentChild.h"
+#include "TVChild.h"
+#include "TVIPCService.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+namespace
+{
+
+TVChild* sTVChild;
+
+} // anonymous
+
+NS_IMPL_ISUPPORTS(TVIPCService, nsITVService)
+
+TVIPCService::TVIPCService()
+{
+ ContentChild* contentChild = ContentChild::GetSingleton();
+ if (NS_WARN_IF(!contentChild)) {
+ return;
+ }
+ sTVChild = new TVChild(this);
+ NS_WARN_IF(!contentChild->SendPTVConstructor(sTVChild));
+}
+
+/* virtual */
+TVIPCService::~TVIPCService() { sTVChild = nullptr; }
+
+NS_IMETHODIMP
+TVIPCService::RegisterSourceListener(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVSourceListener* aListener)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(!aTunerId.IsEmpty());
+ MOZ_ASSERT(!aSourceType.IsEmpty());
+ MOZ_ASSERT(aListener);
+
+ mSourceListenerTuples.AppendElement(new TVSourceListenerTuple(
+ nsString(aTunerId), nsString(aSourceType), aListener));
+
+ if (sTVChild) {
+ NS_WARN_IF(!sTVChild->SendRegisterSourceHandler(nsAutoString(aTunerId),
+ nsAutoString(aSourceType)));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+TVIPCService::UnregisterSourceListener(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVSourceListener* aListener)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(!aTunerId.IsEmpty());
+ MOZ_ASSERT(!aSourceType.IsEmpty());
+ MOZ_ASSERT(aListener);
+
+ for (uint32_t i = 0; i < mSourceListenerTuples.Length(); i++) {
+ const UniquePtr<TVSourceListenerTuple>& tuple = mSourceListenerTuples[i];
+ if (aTunerId.Equals(Get<0>(*tuple)) && aSourceType.Equals(Get<1>(*tuple)) &&
+ aListener == Get<2>(*tuple)) {
+ mSourceListenerTuples.RemoveElementAt(i);
+ break;
+ }
+ }
+
+ if (sTVChild) {
+ NS_WARN_IF(!sTVChild->SendUnregisterSourceHandler(
+ nsAutoString(aTunerId), nsAutoString(aSourceType)));
+ }
+
+ return NS_OK;
+}
+
+void
+TVIPCService::GetSourceListeners(
+ const nsAString& aTunerId, const nsAString& aSourceType,
+ nsTArray<nsCOMPtr<nsITVSourceListener>>& aListeners) const
+{
+ aListeners.Clear();
+
+ for (uint32_t i = 0; i < mSourceListenerTuples.Length(); i++) {
+ const UniquePtr<TVSourceListenerTuple>& tuple = mSourceListenerTuples[i];
+ nsCOMPtr<nsITVSourceListener> listener = Get<2>(*tuple);
+ if (aTunerId.Equals(Get<0>(*tuple)) && aSourceType.Equals(Get<1>(*tuple))) {
+ aListeners.AppendElement(listener);
+ break;
+ }
+ }
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::GetTuners(nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(aCallback, TVGetTunersRequest());
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::SetSource(const nsAString& aTunerId, const nsAString& aSourceType,
+ nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(aCallback, TVSetSourceRequest(nsAutoString(aTunerId),
+ nsAutoString(aSourceType)));
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::StartScanningChannels(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(aCallback,
+ TVStartScanningChannelsRequest(nsAutoString(aTunerId),
+ nsAutoString(aSourceType)));
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::StopScanningChannels(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(aCallback,
+ TVStopScanningChannelsRequest(nsAutoString(aTunerId),
+ nsAutoString(aSourceType)));
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::ClearScannedChannelsCache()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ return SendRequest(nullptr, TVClearScannedChannelsCacheRequest());
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::SetChannel(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ const nsAString& aChannelNumber,
+ nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(aCallback,
+ TVSetChannelRequest(nsAutoString(aTunerId),
+ nsAutoString(aSourceType),
+ nsAutoString(aChannelNumber)));
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::GetChannels(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(
+ aCallback,
+ TVGetChannelsRequest(nsAutoString(aTunerId), nsAutoString(aSourceType)));
+}
+
+/* virtual */ NS_IMETHODIMP
+TVIPCService::GetPrograms(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ const nsAString& aChannelNumber, uint64_t startTime,
+ uint64_t endTime, nsITVServiceCallback* aCallback)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!aCallback) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return SendRequest(aCallback,
+ TVGetProgramsRequest(nsAutoString(aTunerId),
+ nsAutoString(aSourceType),
+ nsAutoString(aChannelNumber),
+ startTime, endTime));
+}
+
+nsresult
+TVIPCService::SendRequest(nsITVServiceCallback* aCallback,
+ const TVIPCRequest& aRequest)
+{
+ if (sTVChild) {
+ TVRequestChild* actor = new TVRequestChild(aCallback);
+ NS_WARN_IF(!sTVChild->SendPTVRequestConstructor(actor, aRequest));
+ }
+ return NS_OK;
+}
+
+nsresult
+TVIPCService::NotifyChannelScanned(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVChannelData* aChannelData)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<nsCOMPtr<nsITVSourceListener>> listeners;
+ GetSourceListeners(aTunerId, aSourceType, listeners);
+ for (uint32_t i = 0; i < listeners.Length(); i++) {
+ nsresult rv =
+ listeners[i]->NotifyChannelScanned(aTunerId, aSourceType, aChannelData);
+ NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return NS_OK;
+}
+
+nsresult
+TVIPCService::NotifyChannelScanComplete(const nsAString& aTunerId,
+ const nsAString& aSourceType)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<nsCOMPtr<nsITVSourceListener>> listeners;
+ GetSourceListeners(aTunerId, aSourceType, listeners);
+ for (uint32_t i = 0; i < listeners.Length(); i++) {
+ nsresult rv =
+ listeners[i]->NotifyChannelScanComplete(aTunerId, aSourceType);
+ NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return NS_OK;
+}
+
+nsresult
+TVIPCService::NotifyChannelScanStopped(const nsAString& aTunerId,
+ const nsAString& aSourceType)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<nsCOMPtr<nsITVSourceListener>> listeners;
+ GetSourceListeners(aTunerId, aSourceType, listeners);
+ for (uint32_t i = 0; i < listeners.Length(); i++) {
+ nsresult rv = listeners[i]->NotifyChannelScanStopped(aTunerId, aSourceType);
+ NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return NS_OK;
+}
+
+nsresult
+TVIPCService::NotifyEITBroadcasted(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVChannelData* aChannelData,
+ nsITVProgramData** aProgramDataList,
+ uint32_t aCount)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsTArray<nsCOMPtr<nsITVSourceListener>> listeners;
+ GetSourceListeners(aTunerId, aSourceType, listeners);
+ for (uint32_t i = 0; i < listeners.Length(); i++) {
+ nsresult rv = listeners[i]->NotifyEITBroadcasted(
+ aTunerId, aSourceType, aChannelData, aProgramDataList, aCount);
+ NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVIPCService.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* 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_TVIPCService_h
+#define mozilla_dom_TVIPCService_h
+
+#include "mozilla/Tuple.h"
+#include "nsITVService.h"
+#include "nsTArray.h"
+#include "TVTypes.h"
+
+namespace mozilla
+{
+namespace dom
+{
+
+class TVIPCRequest;
+
+class TVIPCService final : public nsITVService
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSITVSERVICE
+
+ TVIPCService();
+
+ nsresult NotifyChannelScanned(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVChannelData* aChannelData);
+
+ nsresult NotifyChannelScanComplete(const nsAString& aTunerId,
+ const nsAString& aSourceType);
+
+ nsresult NotifyChannelScanStopped(const nsAString& aTunerId,
+ const nsAString& aSourceType);
+
+ nsresult NotifyEITBroadcasted(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVChannelData* aChannelData,
+ nsITVProgramData** aProgramDataList,
+ uint32_t aCount);
+
+private:
+ virtual ~TVIPCService();
+
+ void GetSourceListeners(
+ const nsAString& aTunerId, const nsAString& aSourceType,
+ nsTArray<nsCOMPtr<nsITVSourceListener>>& aListeners) const;
+
+ nsresult SendRequest(nsITVServiceCallback* aCallback,
+ const TVIPCRequest& aRequest);
+
+ nsTArray<UniquePtr<TVSourceListenerTuple>> mSourceListenerTuples;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TVIPCService_h
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVParent.cpp
@@ -0,0 +1,600 @@
+/* -*- 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/. */
+
+#include "TVParent.h"
+#include "mozilla/unused.h"
+#include "TVTypes.h"
+#include "TVIPCHelper.h"
+
+namespace mozilla {
+namespace dom {
+
+/*
+ * Implementation of TVParent
+ */
+
+NS_IMPL_ISUPPORTS(TVParent, nsITVSourceListener)
+
+TVParent::TVParent() {}
+
+TVParent::~TVParent() {}
+
+bool
+TVParent::Init()
+{
+ MOZ_ASSERT(!mService);
+ mService = do_GetService(TV_SERVICE_CONTRACTID);
+ return NS_WARN_IF(!mService) ? false : true;
+}
+
+/* virtual */ void
+TVParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+ mService = nullptr;
+}
+
+/* virtual */ bool
+TVParent::RecvPTVRequestConstructor(PTVRequestParent* aActor,
+ const TVIPCRequest& aRequest)
+{
+ TVRequestParent* actor = static_cast<TVRequestParent*>(aActor);
+
+ nsresult rv = NS_ERROR_FAILURE;
+ switch (aRequest.type()) {
+ case TVIPCRequest::TTVGetTunersRequest:
+ rv = actor->DoRequest(aRequest.get_TVGetTunersRequest());
+ break;
+ case TVIPCRequest::TTVSetSourceRequest:
+ rv = actor->DoRequest(aRequest.get_TVSetSourceRequest());
+ break;
+ case TVIPCRequest::TTVStartScanningChannelsRequest:
+ rv = actor->DoRequest(aRequest.get_TVStartScanningChannelsRequest());
+ break;
+ case TVIPCRequest::TTVStopScanningChannelsRequest:
+ rv = actor->DoRequest(aRequest.get_TVStopScanningChannelsRequest());
+ break;
+ case TVIPCRequest::TTVClearScannedChannelsCacheRequest:
+ rv = actor->DoRequest(aRequest.get_TVClearScannedChannelsCacheRequest());
+ break;
+ case TVIPCRequest::TTVSetChannelRequest:
+ rv = actor->DoRequest(aRequest.get_TVSetChannelRequest());
+ break;
+ case TVIPCRequest::TTVGetChannelsRequest:
+ rv = actor->DoRequest(aRequest.get_TVGetChannelsRequest());
+ break;
+ case TVIPCRequest::TTVGetProgramsRequest:
+ rv = actor->DoRequest(aRequest.get_TVGetProgramsRequest());
+ break;
+ default:
+ MOZ_CRASH("Unknown TVIPCRequest type");
+ }
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+}
+
+/* virtual */ PTVRequestParent*
+TVParent::AllocPTVRequestParent(const TVIPCRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ RefPtr<TVRequestParent> actor = new TVRequestParent(mService);
+ return actor.forget().take();
+}
+
+/* virtual */ bool
+TVParent::DeallocPTVRequestParent(PTVRequestParent* aActor)
+{
+ RefPtr<TVRequestParent> actor =
+ dont_AddRef(static_cast<TVRequestParent*>(aActor));
+ return true;
+}
+
+/* virtual */ bool
+TVParent::RecvRegisterSourceHandler(const nsString& aTunerId,
+ const nsString& aSourceType)
+{
+ MOZ_ASSERT(mService);
+ NS_WARN_IF(
+ NS_FAILED(mService->RegisterSourceListener(aTunerId, aSourceType, this)));
+ return true;
+}
+
+/* virtual */ bool
+TVParent::RecvUnregisterSourceHandler(const nsString& aTunerId,
+ const nsString& aSourceType)
+{
+ MOZ_ASSERT(mService);
+ NS_WARN_IF(
+ NS_FAILED(mService->UnregisterSourceListener(aTunerId, aSourceType, this)));
+ return true;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVParent::NotifyChannelScanned(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVChannelData* aChannelData)
+{
+ TVIPCChannelData channelData;
+ PackTVIPCChannelData(aChannelData, channelData);
+ if (NS_WARN_IF(!SendNotifyChannelScanned(nsAutoString(aTunerId),
+ nsAutoString(aSourceType),
+ channelData))) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVParent::NotifyChannelScanComplete(const nsAString& aTunerId,
+ const nsAString& aSourceType)
+{
+ if (NS_WARN_IF(!SendNotifyChannelScanComplete(nsAutoString(aTunerId),
+ nsAutoString(aSourceType)))) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVParent::NotifyChannelScanStopped(const nsAString& aTunerId,
+ const nsAString& aSourceType)
+{
+ if (NS_WARN_IF(!SendNotifyChannelScanStopped(nsAutoString(aTunerId),
+ nsAutoString(aSourceType)))) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVParent::NotifyEITBroadcasted(const nsAString& aTunerId,
+ const nsAString& aSourceType,
+ nsITVChannelData* aChannelData,
+ nsITVProgramData** aProgramDataList,
+ uint32_t aCount)
+{
+ TVIPCChannelData ipcChannelData;
+ nsTArray<TVIPCProgramData> programDataList;
+
+ PackTVIPCChannelData(aChannelData, ipcChannelData);
+ for (uint32_t idx = 0; idx < aCount; idx++) {
+ TVIPCProgramData ipcProgramData;
+ PackTVIPCProgramData(aProgramDataList[idx], ipcProgramData);
+ programDataList.AppendElement(ipcProgramData);
+ }
+
+ if (NS_WARN_IF(!SendNotifyEITBroadcasted(nsAutoString(aTunerId),
+ nsAutoString(aSourceType),
+ ipcChannelData, programDataList))) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/*
+ * Implementation of TVRequestBaseCallback
+ */
+
+class TVRequestBaseCallback : public nsITVServiceCallback
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSITVSERVICECALLBACK
+
+ explicit TVRequestBaseCallback(TVRequestParent* aRequestParent)
+ : mRequestParent(aRequestParent)
+ {
+ MOZ_ASSERT(mRequestParent);
+ }
+
+protected:
+ virtual ~TVRequestBaseCallback() {}
+
+ RefPtr<TVRequestParent> mRequestParent;
+};
+
+NS_IMPL_ISUPPORTS(TVRequestBaseCallback, nsITVServiceCallback)
+
+/* virtual */ NS_IMETHODIMP
+TVRequestBaseCallback::NotifySuccess(nsIArray* aDataList)
+{
+ if (NS_WARN_IF(aDataList)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsresult rv;
+ rv = mRequestParent->SendResponse(TVSuccessResponse());
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/* virtual */ NS_IMETHODIMP
+TVRequestBaseCallback::NotifyError(uint16_t aErrorCode)
+{
+ nsresult rv;
+ rv = mRequestParent->SendResponse(TVErrorResponse(aErrorCode));
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/*
+ * Implementation of TVRequestTunerGetterCallback
+ */
+
+class TVRequestTunerGetterCallback final : public TVRequestBaseCallback
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ explicit TVRequestTunerGetterCallback(TVRequestParent* aRequestParent)
+ : TVRequestBaseCallback(aRequestParent)
+ {
+ }
+
+ NS_IMETHOD NotifySuccess(nsIArray* aDataList) override;
+
+private:
+ ~TVRequestTunerGetterCallback() {}
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(TVRequestTunerGetterCallback,
+ TVRequestBaseCallback)
+
+/* virtual */ NS_IMETHODIMP
+TVRequestTunerGetterCallback::NotifySuccess(nsIArray* aDataList)
+{
+ if (NS_WARN_IF(!aDataList)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ uint32_t length;
+ nsresult rv = aDataList->GetLength(&length);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ nsTArray<TVIPCTunerData> tuners(length);
+ for (uint32_t i = 0; i < length; i++) {
+ nsCOMPtr<nsITVTunerData> tunerData = do_QueryElementAt(aDataList, i);
+ if (NS_WARN_IF(!tunerData)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ TVIPCTunerData ipcTunerData;
+ PackTVIPCTunerData(tunerData, ipcTunerData);
+
+ tuners.AppendElement(ipcTunerData);
+ }
+
+ rv = mRequestParent->SendResponse(TVGetTunersResponse(tuners));
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/*
+ * Implementation of TVRequestSourceSetterCallback
+ */
+
+class TVRequestSourceSetterCallback final : public TVRequestBaseCallback
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ explicit TVRequestSourceSetterCallback(TVRequestParent* aRequestParent)
+ : TVRequestBaseCallback(aRequestParent)
+ {
+ }
+
+ NS_IMETHOD NotifySuccess(nsIArray* aDataList) override;
+
+private:
+ ~TVRequestSourceSetterCallback() {}
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(TVRequestSourceSetterCallback,
+ TVRequestBaseCallback)
+
+/* virtual */ NS_IMETHODIMP
+TVRequestSourceSetterCallback::NotifySuccess(nsIArray* aDataList)
+{
+ if (NS_WARN_IF(!aDataList)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ uint32_t length;
+ nsresult rv = aDataList->GetLength(&length);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ if (NS_WARN_IF(length != 1)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsCOMPtr<nsITVGonkNativeHandleData> handleData =
+ do_QueryElementAt(aDataList, 0);
+ if (NS_WARN_IF(!handleData)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ TVIPCGonkNativeHandleData ipcHandleData;
+ PackTVIPCGonkNativeHandleData(handleData, ipcHandleData);
+ rv = mRequestParent->SendResponse(TVSetSourceResponse(ipcHandleData));
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/*
+ * Implementation of TVRequestChannelSetterCallback
+ */
+
+class TVRequestChannelSetterCallback final : public TVRequestBaseCallback
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ explicit TVRequestChannelSetterCallback(TVRequestParent* aRequestParent)
+ : TVRequestBaseCallback(aRequestParent)
+ {
+ }
+
+ NS_IMETHOD NotifySuccess(nsIArray* aDataList) override;
+
+private:
+ ~TVRequestChannelSetterCallback() {}
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(TVRequestChannelSetterCallback,
+ TVRequestBaseCallback)
+
+/* virtual */ NS_IMETHODIMP
+TVRequestChannelSetterCallback::NotifySuccess(nsIArray* aDataList)
+{
+ if (NS_WARN_IF(!aDataList)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ uint32_t length;
+ nsresult rv = aDataList->GetLength(&length);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ if (NS_WARN_IF(length != 1)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsCOMPtr<nsITVChannelData> channelData = do_QueryElementAt(aDataList, 0);
+ if (NS_WARN_IF(!channelData)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ TVIPCChannelData ipcChannelData;
+
+ PackTVIPCChannelData(channelData, ipcChannelData);
+ rv = mRequestParent->SendResponse(TVSetChannelResponse(ipcChannelData));
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/*
+ * Implementation of TVRequestChannelGetterCallback
+ */
+
+class TVRequestChannelGetterCallback final : public TVRequestBaseCallback
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ explicit TVRequestChannelGetterCallback(TVRequestParent* aRequestParent)
+ : TVRequestBaseCallback(aRequestParent)
+ {
+ }
+
+ NS_IMETHOD NotifySuccess(nsIArray* aDataList) override;
+
+private:
+ ~TVRequestChannelGetterCallback() {}
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(TVRequestChannelGetterCallback,
+ TVRequestBaseCallback)
+
+/* virtual */ NS_IMETHODIMP
+TVRequestChannelGetterCallback::NotifySuccess(nsIArray* aDataList)
+{
+ if (NS_WARN_IF(!aDataList)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ uint32_t length;
+ nsresult rv = aDataList->GetLength(&length);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ nsTArray<TVIPCChannelData> channels(length);
+ for (uint32_t i = 0; i < length; i++) {
+ nsCOMPtr<nsITVChannelData> channelData = do_QueryElementAt(aDataList, i);
+ TVIPCChannelData ipcChannelData;
+
+ if (NS_WARN_IF(!channelData)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ PackTVIPCChannelData(channelData, ipcChannelData);
+ channels.AppendElement(ipcChannelData);
+ }
+
+ rv = mRequestParent->SendResponse(TVGetChannelsResponse(channels));
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/*
+ * Implementation of TVRequestProgramGetterCallback
+ */
+
+class TVRequestProgramGetterCallback final : public TVRequestBaseCallback
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ explicit TVRequestProgramGetterCallback(TVRequestParent* aRequestParent)
+ : TVRequestBaseCallback(aRequestParent)
+ {
+ }
+
+ NS_IMETHOD NotifySuccess(nsIArray* aDataList) override;
+
+private:
+ ~TVRequestProgramGetterCallback() {}
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(TVRequestProgramGetterCallback,
+ TVRequestBaseCallback)
+
+/* virtual */ NS_IMETHODIMP
+TVRequestProgramGetterCallback::NotifySuccess(nsIArray* aDataList)
+{
+ if (NS_WARN_IF(!aDataList)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ uint32_t length;
+ nsresult rv = aDataList->GetLength(&length);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ nsTArray<TVIPCProgramData> programs(length);
+ for (uint32_t i = 0; i < length; i++) {
+ nsCOMPtr<nsITVProgramData> programData = do_QueryElementAt(aDataList, i);
+ if (NS_WARN_IF(!programData)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ TVIPCProgramData ipcProgramData;
+ PackTVIPCProgramData(programData, ipcProgramData);
+ programs.AppendElement(ipcProgramData);
+ }
+
+ rv = mRequestParent->SendResponse(TVGetProgramsResponse(programs));
+ mRequestParent = nullptr;
+
+ return rv;
+}
+
+/*
+ * Implementation of TVRequestParent
+ */
+
+NS_IMPL_ISUPPORTS0(TVRequestParent)
+
+TVRequestParent::TVRequestParent(nsITVService* aService) : mService(aService)
+{
+ MOZ_COUNT_CTOR(TVRequestParent);
+}
+
+TVRequestParent::~TVRequestParent()
+{
+ MOZ_COUNT_DTOR(TVRequestParent);
+
+ mService = nullptr;
+}
+
+/* virtual */ void
+TVRequestParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+ mService = nullptr;
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVGetTunersRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->GetTuners(new TVRequestTunerGetterCallback(this));
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVSetSourceRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->SetSource(aRequest.tunerId(), aRequest.sourceType(),
+ new TVRequestSourceSetterCallback(this));
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVStartScanningChannelsRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->StartScanningChannels(
+ aRequest.tunerId(), aRequest.sourceType(), new TVRequestBaseCallback(this));
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVStopScanningChannelsRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->StopScanningChannels(
+ aRequest.tunerId(), aRequest.sourceType(), new TVRequestBaseCallback(this));
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVClearScannedChannelsCacheRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+
+ nsresult rv = mService->ClearScannedChannelsCache();
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return SendResponse(
+ TVErrorResponse(nsITVServiceCallback::TV_ERROR_FAILURE));
+ }
+
+ return SendResponse(TVSuccessResponse());
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVSetChannelRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->SetChannel(aRequest.tunerId(), aRequest.sourceType(),
+ aRequest.channelNumber(),
+ new TVRequestChannelSetterCallback(this));
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVGetChannelsRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->GetChannels(aRequest.tunerId(), aRequest.sourceType(),
+ new TVRequestChannelGetterCallback(this));
+}
+
+nsresult
+TVRequestParent::DoRequest(const TVGetProgramsRequest& aRequest)
+{
+ MOZ_ASSERT(mService);
+ return mService->GetPrograms(aRequest.tunerId(), aRequest.sourceType(),
+ aRequest.channelNumber(), aRequest.startTime(),
+ aRequest.endTime(),
+ new TVRequestProgramGetterCallback(this));
+}
+
+nsresult
+TVRequestParent::SendResponse(const TVIPCResponse& aResponse)
+{
+ if (NS_WARN_IF(!Send__delete__(this, aResponse))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/tv/ipc/TVParent.h
@@ -0,0 +1,88 @@
+/* -*- 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_TVParent_h__
+#define mozilla_dom_TVParent_h__
+
+#include "mozilla/dom/PTVParent.h"
+#include "mozilla/dom/PTVRequestParent.h"
+#include "mozilla/dom/PTVTypes.h"
+#include "nsITVService.h"
+
+namespace mozilla {
+namespace dom {
+
+class TVParent final : public PTVParent, public nsITVSourceListener
+{
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSITVSOURCELISTENER
+
+ TVParent();
+
+ bool Init();
+
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ virtual bool RecvPTVRequestConstructor(PTVRequestParent* aActor,
+ const TVIPCRequest& aRequest) override;
+
+ virtual PTVRequestParent*
+ AllocPTVRequestParent(const TVIPCRequest& aRequest) override;
+
+ virtual bool DeallocPTVRequestParent(PTVRequestParent* aActor) override;
+
+ virtual bool RecvRegisterSourceHandler(const nsString& aTunerId,
+ const nsString& aSourceType) override;
+
+ virtual bool RecvUnregisterSourceHandler(
+ const nsString& aTunerId, const nsString& aSourceType) override;
+
+private:
+ virtual ~TVParent();
+
+ nsCOMPtr<nsITVService> mService;
+};
+
+class TVRequestParent final : public PTVRequestParent, public nsISupports
+{
+ friend class TVParent;
+
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ explicit TVRequestParent(nsITVService* aService);
+
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ nsresult SendResponse(const TVIPCResponse& aResponse);
+
+private:
+ virtual ~TVRequestParent();
+
+ nsresult DoRequest(const TVGetTunersRequest& aRequest);
+
+ nsresult DoRequest(const TVSetSourceRequest& aRequest);
+
+ nsresult DoRequest(const TVStartScanningChannelsRequest& aRequest);
+
+ nsresult DoRequest(const TVStopScanningChannelsRequest& aRequest);
+
+ nsresult DoRequest(const TVClearScannedChannelsCacheRequest& aRequest);
+
+ nsresult DoRequest(const TVSetChannelRequest& aRequest);
+
+ nsresult DoRequest(const TVGetChannelsRequest& aRequest);
+
+ nsresult DoRequest(const TVGetProgramsRequest& aRequest);
+
+ nsCOMPtr<nsITVService> mService;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TVParent_h__
--- a/dom/tv/moz.build
+++ b/dom/tv/moz.build
@@ -1,29 +1,37 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS.mozilla.dom += [
+ 'ipc/TVChild.h',
+ 'ipc/TVIPCHelper.h',
+ 'ipc/TVIPCService.h',
+ 'ipc/TVParent.h',
'TVChannel.h',
'TVListeners.h',
'TVManager.h',
'TVProgram.h',
'TVServiceCallbacks.h',
'TVServiceFactory.h',
'TVServiceRunnables.h',
'TVSource.h',
'TVTuner.h',
'TVTypes.h',
'TVUtils.h',
]
UNIFIED_SOURCES += [
+ 'ipc/TVChild.cpp',
+ 'ipc/TVIPCHelper.cpp',
+ 'ipc/TVIPCService.cpp',
+ 'ipc/TVParent.cpp',
'TVChannel.cpp',
'TVListeners.cpp',
'TVManager.cpp',
'TVProgram.cpp',
'TVServiceCallbacks.cpp',
'TVServiceFactory.cpp',
'TVSource.cpp',
'TVTuner.cpp',
@@ -35,16 +43,22 @@ XPIDL_SOURCES += [
'nsITVSimulatorService.idl',
]
EXTRA_COMPONENTS += [
'TVSimulatorService.js',
'TVSimulatorService.manifest',
]
+IPDL_SOURCES += [
+ 'ipc/PTV.ipdl',
+ 'ipc/PTVRequest.ipdl',
+ 'ipc/PTVTypes.ipdlh'
+]
+
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
UNIFIED_SOURCES += [
'gonk/TVGonkService.cpp',
];
XPIDL_MODULE = 'dom_tv'
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
--- a/dom/tv/nsITVService.idl
+++ b/dom/tv/nsITVService.idl
@@ -2,22 +2,27 @@
* 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/. */
#include "nsISupports.idl"
interface nsIArray;
%{C++
+#include "nsTArray.h"
+
#define TV_TUNER_DATA_CID \
{ 0x1f36be28, 0xf9fe, 0x2dc3, { 0xbf, 0x2a, 0x17, 0x97, 0x93, 0x40, 0xff, 0xe1 } }
#define TV_TUNER_DATA_CONTRACTID \
"@mozilla.org/tv/tvtunerdata;1"
%}
+[ref] native CStringArray(nsTArray<nsCString>);
+[ref] native ConstCStringArray(const nsTArray<nsCString>);
+
/**
* XPCOM component which acts as the container for tuner data.
*
* NOTE: Use do_CreateInstance() to create the Gecko provided implementation,
* and then uses the setter functions to adjust the properties of the object
* before passing it.
*/
[scriptable, builtinclass, uuid(c6d39e86-022b-4db5-b0df-602abfbeac69)]
@@ -40,25 +45,31 @@ interface nsITVTunerData : nsISupports
* http://seanyhlin.github.io/TV-Manager-API/ for available values.
*
* @param count The number of supported source types.
* @param sourceTypes An array of supported source types.
*/
void getSupportedSourceTypes([optional] out unsigned long count,
[retval, array, size_is(count)] out string sourceTypes);
+ void getSupportedSourceTypesByString([optional] out unsigned long count,
+ out CStringArray sourceTypes);
+
/**
* Set the supported source types of the tuner. Please refer to
* http://seanyhlin.github.io/TV-Manager-API/ for available values.
*
* @param count The number of supported source types.
* @param sourceTypes An array of supported source types.
*/
void setSupportedSourceTypes(in unsigned long count,
[array, size_is(count)] in string sourceTypes);
+
+ void setSupportedSourceTypesByString(in unsigned long count,
+ in ConstCStringArray sourceTypes);
};
%{C++
#define TV_CHANNEL_DATA_CID \
{ 0xdafe6881, 0x0964, 0xdb5b, { 0x59, 0xc6, 0x20, 0x0b, 0xa6, 0x59, 0xe6, 0x68 } }
#define TV_CHANNEL_DATA_CONTRACTID \
"@mozilla.org/tv/tvchanneldata;1"
%}
@@ -112,45 +123,59 @@ interface nsITVProgramData : nsISupports
* http://seanyhlin.github.io/TV-Manager-API/ for available values.
*
* @param count The number of languages.
* @param languages An array of languages.
*/
void getAudioLanguages([optional] out unsigned long count,
[retval, array, size_is(count)] out string languages);
+ void getAudioLanguagesByString([optional] out unsigned long count,
+ out CStringArray languages);
+
+
/**
* Set the audio languages of the program. Please refer to
* http://seanyhlin.github.io/TV-Manager-API/ for available values.
*
* @param count The number of languages.
* @param languages An array of languages.
*/
void setAudioLanguages(in unsigned long count,
[array, size_is(count)] in string languages);
+ void setAudioLanguagesByString(in unsigned long count,
+ in ConstCStringArray languages);
+
/**
* Get the subtitle languages of the program. Please refer to
* http://seanyhlin.github.io/TV-Manager-API/ for available values.
*
* @param count The number of languages.
* @param languages An array of languages.
*/
void getSubtitleLanguages([optional] out unsigned long count,
[retval, array, size_is(count)] out string languages);
+ void getSubtitleLanguagesByString([optional] out unsigned long count,
+ out CStringArray languages);
+
/**
* Set the subtitle languages of the program. Please refer to
* http://seanyhlin.github.io/TV-Manager-API/ for available values.
*
* @param count The number of languages.
* @param languages An array of languages.
*/
void setSubtitleLanguages(in unsigned long count,
[array, size_is(count)] in string languages);
+
+ void setSubtitleLanguagesByString(in unsigned long count,
+ in ConstCStringArray languages);
+
};
[scriptable, builtinclass, uuid(47746633-1b77-4df4-9424-d315bde3d455)]
interface nsITVSourceListener : nsISupports
{
/**
* Called when a channel is detected through scanning (after
* |nsITVService::startScanningChannels()| is invoked and probably before