stagefright: fix TimedEventQueue wakelock

If an event is taking a wakelock, the wakelock must be
released after the event is fired.
If the wakelock is released before and the event execution
implies some sleeps or I/O the system can go idle as
no wakelock is held anymore.

Bug: 11976087.

Change-Id: Ie7df8ed4834952ff818ff27d6be415c0b1794a9f
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index 1a9a26b..da23fea 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -127,7 +127,6 @@
     QueueItem item;
     item.event = event;
     item.realtime_us = realtime_us;
-    item.has_wakelock = false;
 
     if (it == mQueue.begin()) {
         mQueueHeadChangedCondition.signal();
@@ -135,7 +134,7 @@
 
     if (realtime_us > ALooper::GetNowUs() + kWakelockMinDelay) {
         acquireWakeLock_l();
-        item.has_wakelock = true;
+        event->setWakeLock();
     }
     mQueue.insert(it, item);
 
@@ -191,7 +190,7 @@
         ALOGV("cancelling event %d", (*it).event->eventID());
 
         (*it).event->setEventID(0);
-        if ((*it).has_wakelock) {
+        if ((*it).event->hasWakeLock()) {
             releaseWakeLock_l();
         }
         it = mQueue.erase(it);
@@ -289,6 +288,9 @@
         if (event != NULL) {
             // Fire event with the lock NOT held.
             event->fire(this, now_us);
+            if (event->hasWakeLock()) {
+                releaseWakeLock_l();
+            }
         }
     }
 }
@@ -300,9 +302,6 @@
         if ((*it).event->eventID() == id) {
             sp<Event> event = (*it).event;
             event->setEventID(0);
-            if ((*it).has_wakelock) {
-                releaseWakeLock_l();
-            }
             mQueue.erase(it);
             return event;
         }
diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h
index 38a08b1..4e8912d 100644
--- a/media/libstagefright/include/TimedEventQueue.h
+++ b/media/libstagefright/include/TimedEventQueue.h
@@ -33,7 +33,7 @@
 
     struct Event : public RefBase {
         Event()
-            : mEventID(0) {
+            : mEventID(0), mHasWakeLock(false) {
         }
 
         virtual ~Event() {}
@@ -42,6 +42,14 @@
             return mEventID;
         }
 
+        void setWakeLock() {
+            mHasWakeLock = true;
+        }
+
+        bool hasWakeLock() {
+            return mHasWakeLock;
+        }
+
     protected:
         virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0;
 
@@ -49,6 +57,7 @@
         friend class TimedEventQueue;
 
         event_id mEventID;
+        bool mHasWakeLock;
 
         void setEventID(event_id id) {
             mEventID = id;
@@ -118,7 +127,6 @@
     struct QueueItem {
         sp<Event> event;
         int64_t realtime_us;
-        bool has_wakelock;
     };
 
     struct StopEvent : public TimedEventQueue::Event {