RDK Documentation (Open Sourced RDK Components)
AampEventManager.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2021 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 /**
21  * @file AampEventManager.cpp
22  * @brief Event Manager operationss for Aamp
23  */
24 
25 #include "AampEventManager.h"
26 
27 
28 //#define EVENT_DEBUGGING 1
29 
30 
31 /**
32  * @brief GetSourceID - Get the idle task's source ID
33  * @return Source Id
34  */
36 {
37  guint callbackId = 0;
38  GSource *source = g_main_current_source();
39  if (source != NULL)
40  {
41  callbackId = g_source_get_id(source);
42  }
43  return callbackId;
44 }
45 
46 /**
47  * @brief Default Constructor
48  */
49 AampEventManager::AampEventManager(AampLogManager *logObj): mIsFakeTune(false),mLogObj(logObj),
50  mAsyncTuneEnabled(false),mEventPriority(G_PRIORITY_DEFAULT_IDLE),mMutexVar(PTHREAD_MUTEX_INITIALIZER),
51  mPlayerState(eSTATE_IDLE),mEventWorkerDataQue(),mPendingAsyncEvents()
52 {
53  for (int i = 0; i < AAMP_MAX_NUM_EVENTS; i++)
54  {
55  mEventListeners[i] = NULL;
56  mEventStats[i] = 0;
57  }
58 }
59 
60 /**
61  * @brief Destructor Function
62  */
64 {
65 
66  // Clear all event listners and pending events
68  pthread_mutex_lock(&mMutexVar);
69  for (int i = 0; i < AAMP_MAX_NUM_EVENTS; i++)
70  {
71  while (mEventListeners[i] != NULL)
72  {
73  ListenerData* pListener = mEventListeners[i];
74  mEventListeners[i] = pListener->pNext;
75  delete pListener;
76  }
77  }
78  pthread_mutex_unlock(&mMutexVar);
79  pthread_mutex_destroy(&mMutexVar);
80 }
81 
82 /**
83  * @brief FlushPendingEvents - Clear all pending events from EventManager
84  */
86 {
87  pthread_mutex_lock(&mMutexVar);
88  while(!mEventWorkerDataQue.empty())
89  {
90  // Remove each AampEventPtr from the queue , not deleting the Shard_ptr
91  mEventWorkerDataQue.pop();
92  }
93 
94  if (mPendingAsyncEvents.size() > 0)
95  {
96  AAMPLOG_WARN("mPendingAsyncEvents.size - %lu", mPendingAsyncEvents.size());
97  for (AsyncEventListIter it = mPendingAsyncEvents.begin(); it != mPendingAsyncEvents.end(); it++)
98  {
99  if ((it->first != 0) && (it->second))
100  {
101  AAMPLOG_WARN("remove id - %d", (int) it->first);
102  g_source_remove(it->first);
103 
104  }
105  }
106  mPendingAsyncEvents.clear();
107  }
108 
109  for (int i = 0; i < AAMP_MAX_NUM_EVENTS; i++)
110  mEventStats[i] = 0;
111  pthread_mutex_unlock(&mMutexVar);
112 
113 #ifdef EVENT_DEBUGGING
114  for (int i = 0; i < AAMP_MAX_NUM_EVENTS; i++)
115  {
116  AAMPLOG_WARN("EventType[%d]->[%d]",i,mEventStats[i]);
117  }
118 #endif
119 
120 }
121 
122 /**
123  * @brief AddListenerForAllEvents - Register one listener for all events
124  */
126 {
127  if(eventListener != NULL)
128  {
130  }
131  else
132  {
133  AAMPLOG_ERR("Null eventlistner. Failed to register");
134  }
135 }
136 
137 /**
138  * @brief RemoveListenerForAllEvents - Remove listener for all events
139  */
141 {
142  if(eventListener != NULL)
143  {
145  }
146  else
147  {
148  AAMPLOG_ERR("Null eventlistner. Failed to deregister");
149  }
150 }
151 
152 /**
153  * @brief AddEventListener - Register listener for one eventtype
154  */
156 {
157  if ((eventListener != NULL) && (eventType >= AAMP_EVENT_ALL_EVENTS) && (eventType < AAMP_MAX_NUM_EVENTS))
158  {
159  ListenerData* pListener = new ListenerData;
160  if (pListener)
161  {
162  AAMPLOG_INFO("EventType:%d, Listener %p new %p", eventType, eventListener, pListener);
163  pthread_mutex_lock(&mMutexVar);
164  pListener->eventListener = eventListener;
165  pListener->pNext = mEventListeners[eventType];
166  mEventListeners[eventType] = pListener;
167  pthread_mutex_unlock(&mMutexVar);
168  }
169  }
170  else
171  {
172  AAMPLOG_ERR("EventType %d registered out of range",eventType);
173  }
174 }
175 
176 /**
177  * @brief RemoveEventListener - Remove one listener registration for one event
178  */
180 {
181  // listner instance is cleared here , but created outside
182  if ((eventListener != NULL) && (eventType >= AAMP_EVENT_ALL_EVENTS) && (eventType < AAMP_MAX_NUM_EVENTS))
183  {
184  pthread_mutex_lock(&mMutexVar);
185  ListenerData** ppLast = &mEventListeners[eventType];
186  while (*ppLast != NULL)
187  {
188  ListenerData* pListener = *ppLast;
189  if (pListener->eventListener == eventListener)
190  {
191  *ppLast = pListener->pNext;
192  pthread_mutex_unlock(&mMutexVar);
193  AAMPLOG_INFO("Eventtype:%d %p delete %p", eventType, eventListener, pListener);
194  delete pListener;
195  return;
196  }
197  ppLast = &(pListener->pNext);
198  }
199  pthread_mutex_unlock(&mMutexVar);
200  }
201 }
202 
203 /**
204  * @brief IsSpecificEventListenerAvailable - Check if this particular listener present for this event
205  */
207 {
208  bool retVal=false;
209  pthread_mutex_lock(&mMutexVar);
210  if(eventType > AAMP_EVENT_ALL_EVENTS && eventType < AAMP_MAX_NUM_EVENTS && mEventListeners[eventType])
211  {
212  retVal = true;
213  }
214  pthread_mutex_unlock(&mMutexVar);
215  return retVal;
216 }
217 
218 /**
219  * @brief IsEventListenerAvailable - Check if any listners present for this event
220  */
222 {
223  bool retVal=false;
224  pthread_mutex_lock(&mMutexVar);
225  if(eventType >= AAMP_EVENT_TUNED && eventType < AAMP_MAX_NUM_EVENTS && (mEventListeners[AAMP_EVENT_ALL_EVENTS] || mEventListeners[eventType]))
226  {
227  retVal = true;
228  }
229  pthread_mutex_unlock(&mMutexVar);
230  return retVal;
231 }
232 
233 /**
234  * @brief SetFakeTuneFlag - Some events are restricted for FakeTune
235  */
236 void AampEventManager::SetFakeTuneFlag(bool isFakeTuneSetting)
237 {
238  pthread_mutex_lock(&mMutexVar);
239  mIsFakeTune = isFakeTuneSetting;
240  pthread_mutex_unlock(&mMutexVar);
241 }
242 
243 /**
244  * @brief SetAsyncTuneState - Flag for Async Tune
245  */
246 void AampEventManager::SetAsyncTuneState(bool isAsyncTuneSetting)
247 {
248  pthread_mutex_lock(&mMutexVar);
249  mAsyncTuneEnabled = isAsyncTuneSetting;
251  {
253  }
254  else
255  {
256  mEventPriority = G_PRIORITY_DEFAULT_IDLE;
257  }
258  pthread_mutex_unlock(&mMutexVar);
259 }
260 
261 /**
262  * @brief SetPlayerState - Flag to update player state
263  */
265 {
266  pthread_mutex_lock(&mMutexVar);
267  mPlayerState = state;
268  pthread_mutex_unlock(&mMutexVar);
269 }
270 
271 /**
272  * @brief SendEvent - Generic function to send events
273  */
274 void AampEventManager::SendEvent(const AAMPEventPtr &eventData, AAMPEventMode eventMode)
275 {
276  // If some event wants to override to send as Sync ,then override flag to be set
277  // This will go as Sync only if SourceID of thread != 0 , else there is assert catch in SendEventSync
278  AAMPEventType eventType = eventData->getType();
279  if ((eventType < AAMP_EVENT_ALL_EVENTS) || (eventType >= AAMP_MAX_NUM_EVENTS)) //CID:81883 - Resolve OVER_RUN
280  return;
281  if(mIsFakeTune && !(AAMP_EVENT_STATE_CHANGED == eventType && eSTATE_COMPLETE == std::dynamic_pointer_cast<StateChangedEvent>(eventData)->getState()) && !(AAMP_EVENT_EOS == eventType))
282  {
283  AAMPLOG_TRACE("Events are disabled for fake tune");
284  return;
285  }
286 
287  if(eventMode < AAMP_EVENT_DEFAULT_MODE || eventMode > AAMP_EVENT_ASYNC_MODE)
288  eventMode = AAMP_EVENT_DEFAULT_MODE;
289 
291  {
292  guint sId = GetSourceID();
293  // if caller is asking for Sync Event , ensure it has proper source Id, else it has to go async event
294  if(eventMode==AAMP_EVENT_SYNC_MODE && sId != 0)
295  {
296  SendEventSync(eventData);
297  }
298  else if(eventMode==AAMP_EVENT_ASYNC_MODE)
299  {
300  SendEventAsync(eventData);
301  }
302  else
303  {
304  //For other events if asyncTune eneabled or calle from non-UI thread , then send the event as Async
305  if (mAsyncTuneEnabled || sId == 0)
306  {
307  SendEventAsync(eventData);
308  }
309  else
310  {
311  SendEventSync(eventData);
312  }
313  }
314  }
315 }
316 
317 
318 // Worker thread for handling Async Events
319 /**
320  * @brief AsyncEvent - Task function for IdleEvent
321  */
323 {
324  pthread_mutex_lock(&mMutexVar);
325  AAMPEventPtr eventData=NULL;
326  // pop out the event to sent in async mode
327  if(mEventWorkerDataQue.size())
328  {
329  eventData = (AAMPEventPtr)mEventWorkerDataQue.front();
330  mEventWorkerDataQue.pop();
331  }
332  pthread_mutex_unlock(&mMutexVar);
333  // Push the new event in sync mode from the idle task
334  if(eventData && (IsEventListenerAvailable(eventData->getType())) && (mPlayerState != eSTATE_RELEASED)) {
335  SendEventSync(eventData);
336  }
337 }
338 
339 /**
340  * @brief SendEventAsync - Function to send events Async
341  */
342 void AampEventManager::SendEventAsync(const AAMPEventPtr &eventData)
343 {
344  AAMPEventType eventType = eventData->getType();
345  pthread_mutex_lock(&mMutexVar);
346  // Check if already player in release state , then no need to send any events
348  {
349  AAMPLOG_INFO("Sending event %d to AsyncQ", eventType);
350  mEventWorkerDataQue.push(eventData);
351  pthread_mutex_unlock(&mMutexVar);
352  // Every event need a idle task to execute it
353  guint callbackID = g_idle_add_full(mEventPriority, EventManagerThreadFunction, this, NULL);
354  if(callbackID != 0)
355  {
356  SetCallbackAsPending(callbackID);
357  }
358  return;
359  }
360  pthread_mutex_unlock(&mMutexVar);
361  return;
362 }
363 
364 
365 /**
366  * @brief SendEventSync - Function to send events sync
367  */
368 void AampEventManager::SendEventSync(const AAMPEventPtr &eventData)
369 {
370  AAMPEventType eventType = eventData->getType();
371  pthread_mutex_lock(&mMutexVar);
372 #ifdef EVENT_DEBUGGING
373  long long startTime = NOW_STEADY_TS_MS;
374 #endif
375  // Check if already player in release state , then no need to send any events
376  // Its checked again here ,as async events can come to sync mode after playback is stopped
378  {
379  pthread_mutex_unlock(&mMutexVar);
380  return;
381  }
382 
383  mEventStats[eventType]++;
384  if (eventType != AAMP_EVENT_PROGRESS)
385  {
386  if (eventType != AAMP_EVENT_STATE_CHANGED)
387  {
388  AAMPLOG_INFO("(type=%d)", eventType);
389  }
390  else
391  {
392  AAMPLOG_WARN("(type=%d)(state=%d)", eventType, std::dynamic_pointer_cast<StateChangedEvent>(eventData)->getState());
393  }
394  }
395 
396  // Build list of registered event listeners.
397  ListenerData* pList = NULL;
398  ListenerData* pListener = mEventListeners[eventType];
399  while (pListener != NULL)
400  {
401  ListenerData* pNew = new ListenerData;
402  pNew->eventListener = pListener->eventListener;
403  pNew->pNext = pList;
404  pList = pNew;
405  pListener = pListener->pNext;
406  }
407  pListener = mEventListeners[AAMP_EVENT_ALL_EVENTS]; // listeners registered for "all" event types
408  while (pListener != NULL)
409  {
410  ListenerData* pNew = new ListenerData;
411  pNew->eventListener = pListener->eventListener;
412  pNew->pNext = pList;
413  pList = pNew;
414  pListener = pListener->pNext;
415  }
416  pthread_mutex_unlock(&mMutexVar);
417 
418  // After releasing the lock, dispatch each of the registered listeners.
419  // This allows event handlers to add/remove listeners for future events.
420  while (pList != NULL)
421  {
422  ListenerData* pCurrent = pList;
423  if (pCurrent->eventListener != NULL)
424  {
425  pCurrent->eventListener->SendEvent(eventData);
426  }
427  pList = pCurrent->pNext;
428  SAFE_DELETE(pCurrent);
429  }
430 #ifdef EVENT_DEBUGGING
431  AAMPLOG_WARN("TimeTaken for Event %d SyncEvent [%d]",eventType, (NOW_STEADY_TS_MS - startTime));
432 #endif
433 
434 }
435 
436 /**
437  * @brief SetCallbackAsDispatched - Set callbackId as dispatched/done
438  */
440 {
441  pthread_mutex_lock(&mMutexVar);
442  AsyncEventListIter itr = mPendingAsyncEvents.find(id);
443  if(itr != mPendingAsyncEvents.end())
444  {
445  AAMPLOG_TRACE("id:%d in mPendingAsyncEvents, erasing it. State:%d", id,itr->second);
446  assert (itr->second);
447  mPendingAsyncEvents.erase(itr);
448  }
449  else
450  {
451  AAMPLOG_TRACE("id:%d not in mPendingAsyncEvents, insert and mark as not pending", id);
452  mPendingAsyncEvents[id] = false;
453  }
454  pthread_mutex_unlock(&mMutexVar);
455 }
456 
457 /**
458  * @brief SetCallbackAsPending - Set callbackId as Pending/to be done
459  */
461 {
462  pthread_mutex_lock(&mMutexVar);
463  AsyncEventListIter itr = mPendingAsyncEvents.find(id);
464  if(itr != mPendingAsyncEvents.end())
465  {
466  AAMPLOG_TRACE("id:%d already in mPendingAsyncEvents and completed, erase it State:%d",id,itr->second);
467  assert (!itr->second);
468  mPendingAsyncEvents.erase(itr);
469  }
470  else
471  {
472  mPendingAsyncEvents[id] = true;
473  AAMPLOG_TRACE("id:%d in mPendingAsyncEvents, added to list", id);
474  }
475  pthread_mutex_unlock(&mMutexVar);
476 }
AAMP_EVENT_ASYNC_MODE
@ AAMP_EVENT_ASYNC_MODE
Definition: AampEvent.h:101
AampEventManager.h
Event Handler for AAMP Player.
AampEventManager::AampEventManager
AampEventManager(AampLogManager *logObj)
Default Constructor.
Definition: AampEventManager.cpp:49
AampEventManager::mIsFakeTune
bool mIsFakeTune
Definition: AampEventManager.h:59
EventListener
Class for sed event to Listener.
Definition: AampEventListener.h:35
AampEventManager::SetPlayerState
void SetPlayerState(PrivAAMPState state)
SetPlayerState - Flag to update player state.
Definition: AampEventManager.cpp:264
AampEventManager::mEventListeners
ListenerData * mEventListeners[AAMP_MAX_NUM_EVENTS]
Definition: AampEventManager.h:65
EventListener::SendEvent
virtual void SendEvent(const AAMPEventPtr &event)=0
API to send event to event listener Additional processing can be done here if required.
AampEventManager::SetFakeTuneFlag
void SetFakeTuneFlag(bool isFakeTuneSetting)
SetFakeTuneFlag - Some events are restricted for FakeTune.
Definition: AampEventManager.cpp:236
AAMP_EVENT_SYNC_MODE
@ AAMP_EVENT_SYNC_MODE
Definition: AampEvent.h:100
AampEventManager::AsyncEvent
void AsyncEvent()
AsyncEvent - Task function for IdleEvent.
Definition: AampEventManager.cpp:322
ListenerData::eventListener
EventListener * eventListener
Definition: AampEventManager.h:46
AampEventManager::AddEventListener
void AddEventListener(AAMPEventType eventType, EventListener *eventListener)
AddEventListener - Register listener for one eventtype.
Definition: AampEventManager.cpp:155
AampLogManager
AampLogManager Class.
Definition: AampLogManager.h:150
AAMP_EVENT_DEFAULT_MODE
@ AAMP_EVENT_DEFAULT_MODE
Definition: AampEvent.h:99
AampEventManager::mEventPriority
int mEventPriority
Definition: AampEventManager.h:63
ListenerData
Structure of the event listener list.
Definition: AampEventManager.h:45
AAMP_EVENT_STATE_CHANGED
@ AAMP_EVENT_STATE_CHANGED
Definition: AampEvent.h:60
AampEventManager::~AampEventManager
~AampEventManager()
Destructor Function.
Definition: AampEventManager.cpp:63
AAMPEventMode
AAMPEventMode
AAMP event modes.
Definition: AampEvent.h:97
AampEventManager::mPlayerState
PrivAAMPState mPlayerState
Definition: AampEventManager.h:61
AampEventManager::IsSpecificEventListenerAvailable
bool IsSpecificEventListenerAvailable(AAMPEventType eventType)
IsSpecificEventListenerAvailable - Check if this particular listener present for this event.
Definition: AampEventManager.cpp:206
AampEventManager::SendEventAsync
void SendEventAsync(const AAMPEventPtr &eventData)
SendEventAsync - Function to send events Async.
Definition: AampEventManager.cpp:342
eSTATE_RELEASED
@ eSTATE_RELEASED
Definition: AampEvent.h:171
AAMP_EVENT_EOS
@ AAMP_EVENT_EOS
Definition: AampEvent.h:50
AAMP_EVENT_TUNED
@ AAMP_EVENT_TUNED
Definition: AampEvent.h:47
AampEventManager::IsEventListenerAvailable
bool IsEventListenerAvailable(AAMPEventType eventType)
IsEventListenerAvailable - Check if any listners present for this event.
Definition: AampEventManager.cpp:221
AAMPLOG_TRACE
#define AAMPLOG_TRACE(FORMAT,...)
AAMP logging defines, this can be enabled through setLogLevel() as per the need.
Definition: AampLogManager.h:83
PrivAAMPState
PrivAAMPState
Mapping all required status codes based on JS player requirement. These requirements may be forced by...
Definition: AampEvent.h:156
ListenerData::pNext
ListenerData * pNext
Definition: AampEventManager.h:47
AampEventManager::AddListenerForAllEvents
void AddListenerForAllEvents(EventListener *eventListener)
AddListenerForAllEvents - Register one listener for all events.
Definition: AampEventManager.cpp:125
AampEventManager::SetCallbackAsPending
void SetCallbackAsPending(guint id)
SetCallbackAsPending - Set callbackId as Pending/to be done.
Definition: AampEventManager.cpp:460
AampEventManager::mMutexVar
pthread_mutex_t mMutexVar
Definition: AampEventManager.h:62
AAMP_MAX_EVENT_PRIORITY
#define AAMP_MAX_EVENT_PRIORITY
Definition: AampDefine.h:158
AampEventManager::RemoveListenerForAllEvents
void RemoveListenerForAllEvents(EventListener *eventListener)
RemoveListenerForAllEvents - Remove listener for all events.
Definition: AampEventManager.cpp:140
AampEventManager::SendEventSync
void SendEventSync(const AAMPEventPtr &eventData)
SendEventSync - Function to send events sync.
Definition: AampEventManager.cpp:368
AampEventManager::GetSourceID
guint GetSourceID()
GetSourceID - Get the idle task's source ID.
Definition: AampEventManager.cpp:35
AampEventManager::SendEvent
void SendEvent(const AAMPEventPtr &eventData, AAMPEventMode eventMode=AAMP_EVENT_DEFAULT_MODE)
SendEvent - Generic function to send events.
Definition: AampEventManager.cpp:274
AampEventManager::FlushPendingEvents
void FlushPendingEvents()
FlushPendingEvents - Clear all pending events from EventManager.
Definition: AampEventManager.cpp:85
AampEventManager::mAsyncTuneEnabled
bool mAsyncTuneEnabled
Definition: AampEventManager.h:60
AAMPEventType
AAMPEventType
Type of the events sending to the JSPP player.
Definition: AampEvent.h:44
eSTATE_IDLE
@ eSTATE_IDLE
Definition: AampEvent.h:158
AampEventManager::EventManagerThreadFunction
static gboolean EventManagerThreadFunction(gpointer This)
Thread entry function for Async Event Processing.
Definition: AampEventManager.h:98
AampEventManager::SetAsyncTuneState
void SetAsyncTuneState(bool isAsyncTuneSetting)
SetAsyncTuneState - Flag for Async Tune.
Definition: AampEventManager.cpp:246
AAMP_EVENT_PROGRESS
@ AAMP_EVENT_PROGRESS
Definition: AampEvent.h:52
AampEventManager::RemoveEventListener
void RemoveEventListener(AAMPEventType eventType, EventListener *eventListener)
RemoveEventListener - Remove one listener registration for one event.
Definition: AampEventManager.cpp:179
AAMP_EVENT_ALL_EVENTS
@ AAMP_EVENT_ALL_EVENTS
Definition: AampEvent.h:46
eSTATE_COMPLETE
@ eSTATE_COMPLETE
Definition: AampEvent.h:169
AampEventManager::mEventStats
int mEventStats[AAMP_MAX_NUM_EVENTS]
Definition: AampEventManager.h:66
AampEventManager::SetCallbackAsDispatched
void SetCallbackAsDispatched(guint id)
SetCallbackAsDispatched - Set callbackId as dispatched/done.
Definition: AampEventManager.cpp:439