f0f0e4c2bce8c7d9616311699c2dc9c6398897bc
[vuplus_xbmc] / xbmc / addons / AddonCallbacksPVR.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "Application.h"
22 #include "AddonCallbacksPVR.h"
23 #include "settings/AdvancedSettings.h"
24 #include "utils/log.h"
25 #include "dialogs/GUIDialogKaiToast.h"
26
27 #include "epg/Epg.h"
28 #include "pvr/PVRManager.h"
29 #include "pvr/channels/PVRChannelGroupsContainer.h"
30 #include "pvr/channels/PVRChannelGroupInternal.h"
31 #include "pvr/addons/PVRClient.h"
32 #include "pvr/recordings/PVRRecordings.h"
33 #include "pvr/timers/PVRTimers.h"
34 #include "pvr/timers/PVRTimerInfoTag.h"
35
36 using namespace PVR;
37 using namespace EPG;
38
39 namespace ADDON
40 {
41
42 CAddonCallbacksPVR::CAddonCallbacksPVR(CAddon* addon)
43 {
44   m_addon     = addon;
45   m_callbacks = new CB_PVRLib;
46
47   /* write XBMC PVR specific add-on function addresses to callback table */
48   m_callbacks->TransferEpgEntry           = PVRTransferEpgEntry;
49   m_callbacks->TransferChannelEntry       = PVRTransferChannelEntry;
50   m_callbacks->TransferTimerEntry         = PVRTransferTimerEntry;
51   m_callbacks->TransferRecordingEntry     = PVRTransferRecordingEntry;
52   m_callbacks->AddMenuHook                = PVRAddMenuHook;
53   m_callbacks->Recording                  = PVRRecording;
54   m_callbacks->TriggerChannelUpdate       = PVRTriggerChannelUpdate;
55   m_callbacks->TriggerChannelGroupsUpdate = PVRTriggerChannelGroupsUpdate;
56   m_callbacks->TriggerTimerUpdate         = PVRTriggerTimerUpdate;
57   m_callbacks->TriggerRecordingUpdate     = PVRTriggerRecordingUpdate;
58   m_callbacks->TriggerEpgUpdate           = PVRTriggerEpgUpdate;
59   m_callbacks->FreeDemuxPacket            = PVRFreeDemuxPacket;
60   m_callbacks->AllocateDemuxPacket        = PVRAllocateDemuxPacket;
61   m_callbacks->TransferChannelGroup       = PVRTransferChannelGroup;
62   m_callbacks->TransferChannelGroupMember = PVRTransferChannelGroupMember;
63 }
64
65 CAddonCallbacksPVR::~CAddonCallbacksPVR()
66 {
67   /* delete the callback table */
68   delete m_callbacks;
69 }
70
71 CPVRClient *CAddonCallbacksPVR::GetPVRClient(void *addonData)
72 {
73   CAddonCallbacks *addon = static_cast<CAddonCallbacks *>(addonData);
74   if (!addon || !addon->GetHelperPVR())
75   {
76     CLog::Log(LOGERROR, "PVR - %s - called with a null pointer", __FUNCTION__);
77     return NULL;
78   }
79
80   return dynamic_cast<CPVRClient *>(addon->GetHelperPVR()->m_addon);
81 }
82
83 void CAddonCallbacksPVR::PVRTransferChannelGroup(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP *group)
84 {
85   if (!handle)
86   {
87     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
88     return;
89   }
90
91   CPVRChannelGroups *xbmcGroups = static_cast<CPVRChannelGroups *>(handle->dataAddress);
92   if (!group || !xbmcGroups)
93   {
94     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
95     return;
96   }
97
98   if (strlen(group->strGroupName) == 0)
99   {
100     CLog::Log(LOGERROR, "PVR - %s - empty group name", __FUNCTION__);
101     return;
102   }
103
104   /* transfer this entry to the groups container */
105   CPVRChannelGroup transferGroup(*group);
106   xbmcGroups->UpdateFromClient(transferGroup);
107 }
108
109 void CAddonCallbacksPVR::PVRTransferChannelGroupMember(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL_GROUP_MEMBER *member)
110 {
111   if (!handle)
112   {
113     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
114     return;
115   }
116   
117   CPVRClient *client      = GetPVRClient(addonData);
118   CPVRChannelGroup *group = static_cast<CPVRChannelGroup *>(handle->dataAddress);
119   if (!member || !client || !group)
120   {
121     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
122     return;
123   }
124
125   CPVRChannelPtr channel  = g_PVRChannelGroups->GetByUniqueID(member->iChannelUniqueId, client->GetID());
126   if (!channel)
127   {
128     CLog::Log(LOGERROR, "PVR - %s - cannot find group '%s' or channel '%d'", __FUNCTION__, member->strGroupName, member->iChannelUniqueId);
129   }
130   else if (group->IsRadio() == channel->IsRadio())
131   {
132     /* transfer this entry to the group */
133     group->AddToGroup(*channel, member->iChannelNumber);
134   }
135 }
136
137 void CAddonCallbacksPVR::PVRTransferEpgEntry(void *addonData, const ADDON_HANDLE handle, const EPG_TAG *epgentry)
138 {
139   if (!handle)
140   {
141     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
142     return;
143   }
144
145   CEpg *xbmcEpg = static_cast<CEpg *>(handle->dataAddress);
146   if (!xbmcEpg)
147   {
148     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
149     return;
150   }
151
152   /* transfer this entry to the epg */
153   xbmcEpg->UpdateEntry(epgentry, handle->dataIdentifier == 1 /* update db */);
154 }
155
156 void CAddonCallbacksPVR::PVRTransferChannelEntry(void *addonData, const ADDON_HANDLE handle, const PVR_CHANNEL *channel)
157 {
158   if (!handle)
159   {
160     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
161     return;
162   }
163
164   CPVRClient *client                     = GetPVRClient(addonData);
165   CPVRChannelGroupInternal *xbmcChannels = static_cast<CPVRChannelGroupInternal *>(handle->dataAddress);
166   if (!channel || !client || !xbmcChannels)
167   {
168     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
169     return;
170   }
171
172   /* transfer this entry to the internal channels group */
173   CPVRChannel transferChannel(*channel, client->GetID());
174   xbmcChannels->UpdateFromClient(transferChannel);
175 }
176
177 void CAddonCallbacksPVR::PVRTransferRecordingEntry(void *addonData, const ADDON_HANDLE handle, const PVR_RECORDING *recording)
178 {
179   if (!handle)
180   {
181     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
182     return;
183   }
184
185   CPVRClient *client             = GetPVRClient(addonData);
186   CPVRRecordings *xbmcRecordings = static_cast<CPVRRecordings *>(handle->dataAddress);
187   if (!recording || !client || !xbmcRecordings)
188   {
189     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
190     return;
191   }
192
193   /* transfer this entry to the recordings container */
194   CPVRRecording transferRecording(*recording, client->GetID());
195   xbmcRecordings->UpdateFromClient(transferRecording);
196 }
197
198 void CAddonCallbacksPVR::PVRTransferTimerEntry(void *addonData, const ADDON_HANDLE handle, const PVR_TIMER *timer)
199 {
200   if (!handle)
201   {
202     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
203     return;
204   }
205
206   CPVRClient *client     = GetPVRClient(addonData);
207   CPVRTimers *xbmcTimers = static_cast<CPVRTimers *>(handle->dataAddress);
208   if (!timer || !client || !xbmcTimers)
209   {
210     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
211     return;
212   }
213
214   CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(timer->iClientChannelUid, client->GetID());
215   if (!channel)
216   {
217     CLog::Log(LOGERROR, "PVR - %s - cannot find channel %d on client %d", __FUNCTION__, timer->iClientChannelUid, client->GetID());
218     return;
219   }
220
221   /* transfer this entry to the timers container */
222   CPVRTimerInfoTag transferTimer(*timer, channel, client->GetID());
223   xbmcTimers->UpdateFromClient(transferTimer);
224 }
225
226 void CAddonCallbacksPVR::PVRAddMenuHook(void *addonData, PVR_MENUHOOK *hook)
227 {
228   CPVRClient *client = GetPVRClient(addonData);
229   if (!hook || !client)
230   {
231     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
232     return;
233   }
234
235   PVR_MENUHOOKS *hooks = client->GetMenuHooks();
236   if (hooks)
237   {
238     PVR_MENUHOOK hookInt;
239     hookInt.iHookId            = hook->iHookId;
240     hookInt.iLocalizedStringId = hook->iLocalizedStringId;
241     hookInt.category           = hook->category;
242
243     /* add this new hook */
244     hooks->push_back(hookInt);
245   }
246 }
247
248 void CAddonCallbacksPVR::PVRRecording(void *addonData, const char *strName, const char *strFileName, bool bOnOff)
249 {
250   CPVRClient *client = GetPVRClient(addonData);
251   if (!client || !strFileName)
252   {
253     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
254     return;
255   }
256
257   CStdString strLine1;
258   if (bOnOff)
259     strLine1.Format(g_localizeStrings.Get(19197), client->Name());
260   else
261     strLine1.Format(g_localizeStrings.Get(19198), client->Name());
262
263   CStdString strLine2;
264   if (strName)
265     strLine2 = strName;
266   else if (strFileName)
267     strLine2 = strFileName;
268
269   /* display a notification for 5 seconds */
270   CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, strLine1, strLine2, 5000, false);
271
272   CLog::Log(LOGDEBUG, "PVR - %s - recording %s on client '%s'. name='%s' filename='%s'",
273       __FUNCTION__, bOnOff ? "started" : "finished", client->Name().c_str(), strName, strFileName);
274 }
275
276 void CAddonCallbacksPVR::PVRTriggerChannelUpdate(void *addonData)
277 {
278   /* update the channels table in the next iteration of the pvrmanager's main loop */
279   g_PVRManager.TriggerChannelsUpdate();
280 }
281
282 void CAddonCallbacksPVR::PVRTriggerTimerUpdate(void *addonData)
283 {
284   /* update the timers table in the next iteration of the pvrmanager's main loop */
285   g_PVRManager.TriggerTimersUpdate();
286 }
287
288 void CAddonCallbacksPVR::PVRTriggerRecordingUpdate(void *addonData)
289 {
290   /* update the recordings table in the next iteration of the pvrmanager's main loop */
291   g_PVRManager.TriggerRecordingsUpdate();
292 }
293
294 void CAddonCallbacksPVR::PVRTriggerChannelGroupsUpdate(void *addonData)
295 {
296   /* update all channel groups in the next iteration of the pvrmanager's main loop */
297   g_PVRManager.TriggerChannelGroupsUpdate();
298 }
299
300 void CAddonCallbacksPVR::PVRTriggerEpgUpdate(void *addonData, unsigned int iChannelUid)
301 {
302   // get the client
303   CPVRClient *client = GetPVRClient(addonData);
304   if (!client)
305   {
306     CLog::Log(LOGERROR, "PVR - %s - invalid handler data", __FUNCTION__);
307     return;
308   }
309
310   // get the channel
311   CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(iChannelUid, client->GetID());
312   CEpg* epg(NULL);
313   // get the EPG for the channel
314   if (!channel || (epg = channel->GetEPG()) == NULL)
315   {
316     CLog::Log(LOGERROR, "PVR - %s - invalid channel or channel doesn't have an EPG", __FUNCTION__);
317     return;
318   }
319
320   // force an update
321   epg->ForceUpdate();
322 }
323
324 void CAddonCallbacksPVR::PVRFreeDemuxPacket(void *addonData, DemuxPacket* pPacket)
325 {
326   CDVDDemuxUtils::FreeDemuxPacket(pPacket);
327 }
328
329 DemuxPacket* CAddonCallbacksPVR::PVRAllocateDemuxPacket(void *addonData, int iDataSize)
330 {
331   return CDVDDemuxUtils::AllocateDemuxPacket(iDataSize);
332 }
333
334 }; /* namespace ADDON */