1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_DISCONNECT_WAITER_H
18 #define ANDROID_DISCONNECT_WAITER_H
19 
20 #include <gui/IConsumerListener.h>
21 
22 #include <utils/Condition.h>
23 #include <utils/Mutex.h>
24 
25 namespace android {
26 
27 // Note that GLConsumer will lose the notifications
28 // onBuffersReleased and onFrameAvailable as there is currently
29 // no way to forward the events.  This DisconnectWaiter will not let the
30 // disconnect finish until finishDisconnect() is called.  It will
31 // also block until a disconnect is called
32 class DisconnectWaiter : public BnConsumerListener {
33 public:
DisconnectWaiter()34     DisconnectWaiter () :
35         mWaitForDisconnect(false),
36         mPendingFrames(0) {
37     }
38 
waitForFrame()39     void waitForFrame() {
40         Mutex::Autolock lock(mMutex);
41         while (mPendingFrames == 0) {
42             mFrameCondition.wait(mMutex);
43         }
44         mPendingFrames--;
45     }
46 
onFrameAvailable(const BufferItem &)47     virtual void onFrameAvailable(const BufferItem& /* item */) {
48         Mutex::Autolock lock(mMutex);
49         mPendingFrames++;
50         mFrameCondition.signal();
51     }
52 
onBuffersReleased()53     virtual void onBuffersReleased() {
54         Mutex::Autolock lock(mMutex);
55         while (!mWaitForDisconnect) {
56             mDisconnectCondition.wait(mMutex);
57         }
58     }
59 
onSidebandStreamChanged()60     virtual void onSidebandStreamChanged() {}
61 
finishDisconnect()62     void finishDisconnect() {
63         Mutex::Autolock lock(mMutex);
64         mWaitForDisconnect = true;
65         mDisconnectCondition.signal();
66     }
67 
68 private:
69     Mutex mMutex;
70 
71     bool mWaitForDisconnect;
72     Condition mDisconnectCondition;
73 
74     int mPendingFrames;
75     Condition mFrameCondition;
76 };
77 
78 } // namespace android
79 
80 #endif
81