11a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis/*
21a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * Copyright (C) 2010 The Android Open Source Project
31a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *
41a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
51a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * you may not use this file except in compliance with the License.
61a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * You may obtain a copy of the License at
71a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *
81a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
91a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis *
101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * Unless required by applicable law or agreed to in writing, software
111a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
121a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * See the License for the specific language governing permissions and
141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis * limitations under the License.
151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis */
161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#ifndef ANDROID_GUI_CONSUMERBASE_H
181a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#define ANDROID_GUI_CONSUMERBASE_H
191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <ui/GraphicBuffer.h>
231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
241a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <utils/String8.h>
251a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <utils/Vector.h>
261a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <utils/threads.h>
271a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
281a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisnamespace android {
291a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// ----------------------------------------------------------------------------
301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisclass String8;
321a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
331a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// ConsumerBase is a base class for BufferQueue consumer end-points. It
341a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// handles common tasks like management of the connection to the BufferQueue
351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// and the buffer pool.
361a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisclass ConsumerBase : public virtual RefBase,
371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        protected BufferQueue::ConsumerListener {
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennispublic:
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    struct FrameAvailableListener : public virtual RefBase {
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // onFrameAvailable() is called each time an additional frame becomes
411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // available for consumption. This means that frames that are queued
421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // while in asynchronous mode only trigger the callback if no previous
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // frames are pending. Frames queued while in synchronous mode always
441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // trigger the callback.
451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        //
461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // This is called without any lock held and can be called concurrently
471a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // by multiple threads.
481a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        virtual void onFrameAvailable() = 0;
491a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    };
501a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
511a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual ~ConsumerBase();
521a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
531a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // abandon frees all the buffers and puts the ConsumerBase into the
541a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // 'abandoned' state.  Once put in this state the ConsumerBase can never
551a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // leave it.  When in the 'abandoned' state, all methods of the
561a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // ISurfaceTexture interface will fail with the NO_INIT error.
571a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    //
581a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // Note that while calling this method causes all the buffers to be freed
591a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // from the perspective of the the ConsumerBase, if there are additional
601a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // references on the buffers (e.g. if a buffer is referenced by a client
611a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // or by OpenGL ES as a texture) then those buffer will remain allocated.
621a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    void abandon();
631a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
641a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // set the name of the ConsumerBase that will be used to identify it in
651a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // log messages.
661a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    void setName(const String8& name);
671a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
681a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // getBufferQueue returns the BufferQueue object to which this
691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // ConsumerBase is connected.
701a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<BufferQueue> getBufferQueue() const;
711a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
721a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // dump writes the current state to a string.  These methods should NOT be
731a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // overridden by child classes.  Instead they should override the
741a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // dumpLocked method, which is called by these methods after locking the
751a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // mutex.
761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    void dump(String8& result) const;
771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // setFrameAvailableListener sets the listener object that will be notified
801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // when a new frame becomes available.
811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisprivate:
841a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ConsumerBase(const ConsumerBase&);
851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    void operator=(const ConsumerBase&);
861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennisprotected:
881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
899fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // ConsumerBase constructs a new ConsumerBase object to consume image
909fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // buffers from the given BufferQueue.
911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ConsumerBase(const sp<BufferQueue> &bufferQueue);
921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // Implementation of the BufferQueue::ConsumerListener interface.  These
941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // calls are used to notify the ConsumerBase of asynchronous events in the
959fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // BufferQueue.  These methods should not need to be overridden by derived
969fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // classes, but if they are overridden the ConsumerBase implementation
979fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // must be called from the derived class.
981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual void onFrameAvailable();
991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual void onBuffersReleased();
1001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // freeBufferLocked frees up the given buffer slot.  If the slot has been
1021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // initialized this will release the reference to the GraphicBuffer in that
1039fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // slot.  Otherwise it has no effect.
1049fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
1059fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // Derived classes should override this method to clean up any state they
1069fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // keep per slot.  If it is overridden, the derived class's implementation
1079fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // must call ConsumerBase::freeBufferLocked.
1081a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    //
1091a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // This method must be called with mMutex locked.
1101a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual void freeBufferLocked(int slotIndex);
1111a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1121a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // abandonLocked puts the BufferQueue into the abandoned state, causing
1131a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // all future operations on it to fail. This method rather than the public
1141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // abandon method should be overridden by child classes to add abandon-
1151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // time behavior.
1161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    //
1179fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // Derived classes should override this method to clean up any object
1189fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // state they keep (as opposed to per-slot state).  If it is overridden,
1199fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // the derived class's implementation must call ConsumerBase::abandonLocked.
1209fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
1211a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // This method must be called with mMutex locked.
1221a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual void abandonLocked();
1231a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1249fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // dumpLocked dumps the current state of the ConsumerBase object to the
1259fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // result string.  Each line is prefixed with the string pointed to by the
1269fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // prefix argument.  The buffer argument points to a buffer that may be
1279fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // used for intermediate formatting data, and the size of that buffer is
1289fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // indicated by the size argument.
1299fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
1309fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // Derived classes should override this method to dump their internal
1319fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // state.  If this method is overridden the derived class's implementation
1329fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // should call ConsumerBase::dumpLocked.
1339fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
1349fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // This method must be called with mMutex locked.
1351a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual void dumpLocked(String8& result, const char* prefix, char* buffer,
1369fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis            size_t size) const;
1371a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // acquireBufferLocked fetches the next buffer from the BufferQueue and
1391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // updates the buffer slot for the buffer returned.
1409fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
1419fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // Derived classes should override this method to perform any
1429fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // initialization that must take place the first time a buffer is assigned
1439fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // to a slot.  If it is overridden the derived class's implementation must
1449fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // call ConsumerBase::acquireBufferLocked.
1451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item);
1461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1471a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // releaseBufferLocked relinquishes control over a buffer, returning that
1481a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // control to the BufferQueue.
1499fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
1509fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // Derived classes should override this method to perform any cleanup that
1519fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // must take place when a buffer is released back to the BufferQueue.  If
1529fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // it is overridden the derived class's implementation must call
1539504eb915c9628e130f45019bdefda0168089886Jesse Hall    // ConsumerBase::releaseBufferLocked.
1541a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    virtual status_t releaseBufferLocked(int buf, EGLDisplay display,
155b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis           EGLSyncKHR eglFence);
156b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis
1579504eb915c9628e130f45019bdefda0168089886Jesse Hall    // addReleaseFence* adds the sync points associated with a fence to the set
158b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    // of sync points that must be reached before the buffer in the given slot
159b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    // may be used after the slot has been released.  This should be called by
160b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    // derived classes each time some asynchronous work is kicked off that
161b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    // references the buffer.
162b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis    status_t addReleaseFence(int slot, const sp<Fence>& fence);
1639504eb915c9628e130f45019bdefda0168089886Jesse Hall    status_t addReleaseFenceLocked(int slot, const sp<Fence>& fence);
1641a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1651a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // Slot contains the information and object references that
1661a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // ConsumerBase maintains about a BufferQueue buffer slot.
1671a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    struct Slot {
1681a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if
1691a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // no Gralloc buffer is in the slot.
1701a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        sp<GraphicBuffer> mGraphicBuffer;
1711a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1721a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // mFence is a fence which will signal when the buffer associated with
1731a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // this buffer slot is no longer being used by the consumer and can be
1741a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // overwritten. The buffer can be dequeued before the fence signals;
1751a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        // the producer is responsible for delaying writes until it signals.
1761a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        sp<Fence> mFence;
1771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    };
1781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // mSlots stores the buffers that have been allocated by the BufferQueue
1801a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // for each buffer slot.  It is initialized to null pointers, and gets
1811a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // filled in with the result of BufferQueue::acquire when the
1821a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // client dequeues a buffer from a
1831a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // slot that has not yet been used. The buffer allocated to a slot will also
1841a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // be replaced if the requested buffer usage or geometry differs from that
1851a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // of the buffer allocated to a slot.
1861a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS];
1871a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1881a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // mAbandoned indicates that the BufferQueue will no longer be used to
1891a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // consume images buffers pushed to it using the ISurfaceTexture
1901a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // interface. It is initialized to false, and set to true in the abandon
1911a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // method.  A BufferQueue that has been abandoned will return the NO_INIT
1921a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // error from all IConsumerBase methods capable of returning an error.
1931a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    bool mAbandoned;
1941a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1951a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // mName is a string used to identify the ConsumerBase in log messages.
1961a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // It can be set by the setName method.
1971a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    String8 mName;
1981a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
1991a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // mFrameAvailableListener is the listener object that will be called when a
2001a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // new frame becomes available. If it is not NULL it will be called from
2011a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // queueBuffer.
2021a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FrameAvailableListener> mFrameAvailableListener;
2031a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2041a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // The ConsumerBase has-a BufferQueue and is responsible for creating this object
2051a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // if none is supplied
2061a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<BufferQueue> mBufferQueue;
2071a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2081a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // mMutex is the mutex used to prevent concurrent access to the member
2091a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    // variables of ConsumerBase objects. It must be locked whenever the
2109fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // member variables are accessed or when any of the *Locked methods are
2119fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // called.
2129fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    //
2139fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis    // This mutex is intended to be locked by derived classes.
2141a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    mutable Mutex mMutex;
2151a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis};
2161a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2171a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis// ----------------------------------------------------------------------------
2181a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis}; // namespace android
2191a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
2201a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#endif // ANDROID_GUI_CONSUMERBASE_H
221