/*
* Copyright (C) 2012-2013 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, see
* .
*
*/
#include "Application.h"
#include "AddonCallbacksPVR.h"
#include "settings/AdvancedSettings.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
#include "dialogs/GUIDialogKaiToast.h"
#include "epg/EpgContainer.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
#include "pvr/addons/PVRClient.h"
#include "pvr/recordings/PVRRecordings.h"
#include "pvr/timers/PVRTimers.h"
#include "pvr/timers/PVRTimerInfoTag.h"
using namespace PVR;
using namespace EPG;
namespace ADDON
{
CAddonCallbacksPVR::CAddonCallbacksPVR(CAddon* addon)
{
m_addon = addon;
m_callbacks = new CB_PVRLib;
/* write XBMC PVR specific add-on function addresses to callback table */
m_callbacks->TransferEpgEntry = PVRTransferEpgEntry;
m_callbacks->TransferChannelEntry = PVRTransferChannelEntry;
m_callbacks->TransferTimerEntry = PVRTransferTimerEntry;
m_callbacks->TransferRecordingEntry = PVRTransferRecordingEntry;
m_callbacks->AddMenuHook = PVRAddMenuHook;
m_callbacks->Recording = PVRRecording;
m_callbacks->TriggerChannelUpdate = PVRTriggerChannelUpdate;
m_callbacks->TriggerChannelGroupsUpdate = PVRTriggerChannelGroupsUpdate;
m_callbacks->TriggerTimerUpdate = PVRTriggerTimerUpdate;
m_callbacks->TriggerRecordingUpdate = PVRTriggerRecordingUpdate;
m_callbacks->TriggerEpgUpdate = PVRTriggerEpgUpdate;
m_callbacks->FreeDemuxPacket = PVRFreeDemuxPacket;
m_callbacks->AllocateDemuxPacket = PVRAllocateDemuxPacket;
m_callbacks->TransferChannelGroup = PVRTransferChannelGroup;
m_callbacks->TransferChannelGroupMember = PVRTransferChannelGroupMember;
}
CAddonCallbacksPVR::~CAddonCallbacksPVR()
{
/* delete the callback table */
delete m_callbacks;
}
CPVRClient *CAddonCallbacksPVR::GetPVRClient(void *addonData)
{
CAddonCallbacks *addon = static_cast(addonData);
if (!addon || !addon->GetHelperPVR())
{
CLog::Log(LOGERROR, "PVR - %s - called with a null pointer", __FUNCTION__);
return NULL;
}
return dynamic_cast(addon->GetHelperPVR()->m_addon);
}
void CAddonCallbacksPVR::PVRTransferChannelGroup(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP *group)
{
if (!handle)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRChannelGroups *xbmcGroups = static_cast(handle->dataAddress);
if (!group || !xbmcGroups)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
if (strlen(group->strGroupName) == 0)
{
CLog::Log(LOGERROR, "PVR - %s - empty group name", __FUNCTION__);
return;
}
/* transfer this entry to the groups container */
CPVRChannelGroup transferGroup(*group);
xbmcGroups->UpdateFromClient(transferGroup);
}
void CAddonCallbacksPVR::PVRTransferChannelGroupMember(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP_MEMBER *member)
{
if (!handle)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRClient *client = GetPVRClient(addonData);
CPVRChannelGroup *group = static_cast(handle->dataAddress);
if (!member || !client || !group)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(member->iChannelUniqueId, client->GetID());
if (!channel)
{
CLog::Log(LOGERROR, "PVR - %s - cannot find group '%s' or channel '%d'", __FUNCTION__, member->strGroupName, member->iChannelUniqueId);
}
else if (group->IsRadio() == channel->IsRadio())
{
/* transfer this entry to the group */
group->AddToGroup(channel, member->iChannelNumber);
}
}
void CAddonCallbacksPVR::PVRTransferEpgEntry(void *addonData, const ADDON_HANDLE handle, const EPG_TAG *epgentry)
{
if (!handle)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CEpg *xbmcEpg = static_cast(handle->dataAddress);
if (!xbmcEpg)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
/* transfer this entry to the epg */
xbmcEpg->UpdateEntry(epgentry, handle->dataIdentifier == 1 /* update db */);
}
void CAddonCallbacksPVR::PVRTransferChannelEntry(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL *channel)
{
if (!handle)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRClient *client = GetPVRClient(addonData);
CPVRChannelGroupInternal *xbmcChannels = static_cast(handle->dataAddress);
if (!channel || !client || !xbmcChannels)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
/* transfer this entry to the internal channels group */
CPVRChannelPtr transferChannel(new CPVRChannel(*channel, client->GetID()));
xbmcChannels->UpdateFromClient(transferChannel);
}
void CAddonCallbacksPVR::PVRTransferRecordingEntry(void *addonData, const ADDON_HANDLE handle, const PVR_RECORDING *recording)
{
if (!handle)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRClient *client = GetPVRClient(addonData);
CPVRRecordings *xbmcRecordings = static_cast(handle->dataAddress);
if (!recording || !client || !xbmcRecordings)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
/* transfer this entry to the recordings container */
CPVRRecordingPtr transferRecording(new CPVRRecording(*recording, client->GetID()));
xbmcRecordings->UpdateFromClient(transferRecording);
}
void CAddonCallbacksPVR::PVRTransferTimerEntry(void *addonData, const ADDON_HANDLE handle, const PVR_TIMER *timer)
{
if (!handle)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRClient *client = GetPVRClient(addonData);
CPVRTimers *xbmcTimers = static_cast(handle->dataAddress);
if (!timer || !client || !xbmcTimers)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(timer->iClientChannelUid, client->GetID());
if (!channel)
{
CLog::Log(LOGERROR, "PVR - %s - cannot find channel %d on client %d", __FUNCTION__, timer->iClientChannelUid, client->GetID());
return;
}
/* transfer this entry to the timers container */
CPVRTimerInfoTag transferTimer(*timer, channel, client->GetID());
xbmcTimers->UpdateFromClient(transferTimer);
}
void CAddonCallbacksPVR::PVRAddMenuHook(void *addonData, PVR_MENUHOOK *hook)
{
CPVRClient *client = GetPVRClient(addonData);
if (!hook || !client)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
PVR_MENUHOOKS *hooks = client->GetMenuHooks();
if (hooks)
{
PVR_MENUHOOK hookInt;
hookInt.iHookId = hook->iHookId;
hookInt.iLocalizedStringId = hook->iLocalizedStringId;
hookInt.category = hook->category;
/* add this new hook */
hooks->push_back(hookInt);
}
}
void CAddonCallbacksPVR::PVRRecording(void *addonData, const char *strName, const char *strFileName, bool bOnOff)
{
CPVRClient *client = GetPVRClient(addonData);
if (!client || !strFileName)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
std::string strLine1;
if (bOnOff)
strLine1 = StringUtils::Format(g_localizeStrings.Get(19197).c_str(), client->Name().c_str());
else
strLine1 = StringUtils::Format(g_localizeStrings.Get(19198).c_str(), client->Name().c_str());
std::string strLine2;
if (strName)
strLine2 = strName;
else if (strFileName)
strLine2 = strFileName;
/* display a notification for 5 seconds */
CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, strLine1, strLine2, 5000, false);
CLog::Log(LOGDEBUG, "PVR - %s - recording %s on client '%s'. name='%s' filename='%s'",
__FUNCTION__, bOnOff ? "started" : "finished", client->Name().c_str(), strName, strFileName);
}
void CAddonCallbacksPVR::PVRTriggerChannelUpdate(void *addonData)
{
/* update the channels table in the next iteration of the pvrmanager's main loop */
g_PVRManager.TriggerChannelsUpdate();
}
void CAddonCallbacksPVR::PVRTriggerTimerUpdate(void *addonData)
{
/* update the timers table in the next iteration of the pvrmanager's main loop */
g_PVRManager.TriggerTimersUpdate();
}
void CAddonCallbacksPVR::PVRTriggerRecordingUpdate(void *addonData)
{
/* update the recordings table in the next iteration of the pvrmanager's main loop */
g_PVRManager.TriggerRecordingsUpdate();
}
void CAddonCallbacksPVR::PVRTriggerChannelGroupsUpdate(void *addonData)
{
/* update all channel groups in the next iteration of the pvrmanager's main loop */
g_PVRManager.TriggerChannelGroupsUpdate();
}
void CAddonCallbacksPVR::PVRTriggerEpgUpdate(void *addonData, unsigned int iChannelUid)
{
// get the client
CPVRClient *client = GetPVRClient(addonData);
if (!client)
{
CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
return;
}
g_EpgContainer.UpdateRequest(client->GetID(), iChannelUid);
}
void CAddonCallbacksPVR::PVRFreeDemuxPacket(void *addonData, DemuxPacket* pPacket)
{
CDVDDemuxUtils::FreeDemuxPacket(pPacket);
}
DemuxPacket* CAddonCallbacksPVR::PVRAllocateDemuxPacket(void *addonData, int iDataSize)
{
return CDVDDemuxUtils::AllocateDemuxPacket(iDataSize);
}
}; /* namespace ADDON */