1/*
2 * Copyright (C) 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_HARDWARE_PRO_CAMERA_H
18#define ANDROID_HARDWARE_PRO_CAMERA_H
19
20#include <utils/Timers.h>
21#include <utils/KeyedVector.h>
22#include <gui/IGraphicBufferProducer.h>
23#include <system/camera.h>
24#include <camera/IProCameraCallbacks.h>
25#include <camera/IProCameraUser.h>
26#include <camera/Camera.h>
27#include <camera/CameraMetadata.h>
28#include <camera/ICameraService.h>
29#include <gui/CpuConsumer.h>
30
31#include <gui/Surface.h>
32
33#include <utils/Condition.h>
34#include <utils/Mutex.h>
35
36#include <camera/CameraBase.h>
37
38struct camera_metadata;
39
40namespace android {
41
42// All callbacks on this class are concurrent
43// (they come from separate threads)
44class ProCameraListener : virtual public RefBase
45{
46public:
47    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
48
49    // Lock has been acquired. Write operations now available.
50    virtual void onLockAcquired() = 0;
51    // Lock has been released with exclusiveUnlock.
52    virtual void onLockReleased() = 0;
53    // Lock has been stolen by another client.
54    virtual void onLockStolen() = 0;
55
56    // Lock free.
57    virtual void onTriggerNotify(int32_t msgType, int32_t ext1, int32_t ext2)
58                                                                            = 0;
59    // onFrameAvailable and OnResultReceived can come in with any order,
60    // use android.sensor.timestamp and LockedBuffer.timestamp to correlate them
61
62    /**
63      * A new metadata buffer has been received.
64      * -- Ownership of request passes on to the callee, free with
65      *    free_camera_metadata.
66      */
67    virtual void onResultReceived(int32_t frameId, camera_metadata* result) = 0;
68
69    // TODO: make onFrameAvailable pure virtual
70
71    // A new frame buffer has been received for this stream.
72    // -- This callback only fires for createStreamCpu streams
73    // -- A buffer may be obtained by calling cpuConsumer->lockNextBuffer
74    // -- Use buf.timestamp to correlate with result's android.sensor.timestamp
75    // -- The buffer should be accessed with CpuConsumer::lockNextBuffer
76    //      and CpuConsumer::unlockBuffer
77    virtual void onFrameAvailable(int /*streamId*/,
78                                  const sp<CpuConsumer>& /*cpuConsumer*/) {
79    }
80
81};
82
83class ProCamera;
84
85template <>
86struct CameraTraits<ProCamera>
87{
88    typedef ProCameraListener     TCamListener;
89    typedef IProCameraUser        TCamUser;
90    typedef IProCameraCallbacks   TCamCallbacks;
91    typedef status_t (ICameraService::*TCamConnectService)(const sp<IProCameraCallbacks>&,
92                                                           int, const String16&, int,
93                                                           /*out*/
94                                                           sp<IProCameraUser>&);
95    static TCamConnectService     fnConnectService;
96};
97
98
99class ProCamera :
100    public CameraBase<ProCamera>,
101    public BnProCameraCallbacks
102{
103public:
104    /**
105     * Connect a shared camera. By default access is restricted to read only
106     * (Lock free) operations. To be able to submit custom requests a lock needs
107     * to be acquired with exclusive[Try]Lock.
108     */
109    static sp<ProCamera> connect(int cameraId);
110    virtual ~ProCamera();
111
112    /**
113     * Exclusive Locks:
114     * - We may request exclusive access to a camera if no other
115     *   clients are using the camera. This works as a traditional
116     *   client, writing/reading any camera state.
117     * - An application opening the camera (a regular 'Camera') will
118     *   always steal away the exclusive lock from a ProCamera,
119     *   this will call onLockReleased.
120     * - onLockAcquired will be called again once it is possible
121     *   to again exclusively lock the camera.
122     *
123     */
124
125    /**
126     * All exclusiveLock/unlock functions are asynchronous. The remote endpoint
127     * shall not block while waiting to acquire the lock. Instead the lock
128     * notifications will come in asynchronously on the listener.
129     */
130
131    /**
132      * Attempt to acquire the lock instantly (non-blocking)
133      * - If this succeeds, you do not need to wait for onLockAcquired
134      *   but the event will still be fired
135      *
136      * Returns -EBUSY if already locked. 0 on success.
137      */
138    status_t exclusiveTryLock();
139    // always returns 0. wait for onLockAcquired before lock is acquired.
140    status_t exclusiveLock();
141    // release a lock if we have one, or cancel the lock request.
142    status_t exclusiveUnlock();
143
144    // exclusive lock = do whatever we want. no lock = read only.
145    bool hasExclusiveLock();
146
147    /**
148     * < 0 error, >= 0 the request ID. streaming to have the request repeat
149     *    until cancelled.
150     * The request queue is flushed when a lock is released or stolen
151     *    if not locked will return PERMISSION_DENIED
152     */
153    int submitRequest(const struct camera_metadata* metadata,
154                                                        bool streaming = false);
155    // if not locked will return PERMISSION_DENIED, BAD_VALUE if requestId bad
156    status_t cancelRequest(int requestId);
157
158    /**
159     * Ask for a stream to be enabled.
160     * Lock free. Service maintains counter of streams.
161     */
162    status_t requestStream(int streamId);
163// TODO: remove requestStream, its useless.
164
165    /**
166      * Delete a stream.
167      * Lock free.
168      *
169      * NOTE: As a side effect this cancels ALL streaming requests.
170      *
171      * Errors: BAD_VALUE if unknown stream ID.
172      *         PERMISSION_DENIED if the stream wasn't yours
173      */
174    status_t deleteStream(int streamId);
175
176    /**
177      * Create a new HW stream, whose sink will be the window.
178      * Lock free. Service maintains counter of streams.
179      * Errors: -EBUSY if too many streams created
180      */
181    status_t createStream(int width, int height, int format,
182                          const sp<Surface>& surface,
183                          /*out*/
184                          int* streamId);
185
186    /**
187      * Create a new HW stream, whose sink will be the SurfaceTexture.
188      * Lock free. Service maintains counter of streams.
189      * Errors: -EBUSY if too many streams created
190      */
191    status_t createStream(int width, int height, int format,
192                          const sp<IGraphicBufferProducer>& bufferProducer,
193                          /*out*/
194                          int* streamId);
195    status_t createStreamCpu(int width, int height, int format,
196                          int heapCount,
197                          /*out*/
198                          sp<CpuConsumer>* cpuConsumer,
199                          int* streamId);
200    status_t createStreamCpu(int width, int height, int format,
201                          int heapCount,
202                          bool synchronousMode,
203                          /*out*/
204                          sp<CpuConsumer>* cpuConsumer,
205                          int* streamId);
206
207    // Create a request object from a template.
208    status_t createDefaultRequest(int templateId,
209                                 /*out*/
210                                  camera_metadata** request) const;
211
212    // Get static camera metadata
213    camera_metadata* getCameraInfo(int cameraId);
214
215    // Blocks until a frame is available (CPU streams only)
216    // - Obtain the frame data by calling CpuConsumer::lockNextBuffer
217    // - Release the frame data after use with CpuConsumer::unlockBuffer
218    // Return value:
219    // - >0 - number of frames available to be locked
220    // - <0 - error (refer to error codes)
221    // Error codes:
222    // -ETIMEDOUT if it took too long to get a frame
223    int waitForFrameBuffer(int streamId);
224
225    // Blocks until a metadata result is available
226    // - Obtain the metadata by calling consumeFrameMetadata()
227    // Error codes:
228    // -ETIMEDOUT if it took too long to get a frame
229    status_t waitForFrameMetadata();
230
231    // Get the latest metadata. This is destructive.
232    // - Calling this repeatedly will produce empty metadata objects.
233    // - Use waitForFrameMetadata to sync until new data is available.
234    CameraMetadata consumeFrameMetadata();
235
236    // Convenience method to drop frame buffers (CPU streams only)
237    // Return values:
238    //  >=0 - number of frames dropped (up to count)
239    //  <0  - error code
240    // Error codes:
241    //   BAD_VALUE - invalid streamId or count passed
242    int dropFrameBuffer(int streamId, int count);
243
244protected:
245    ////////////////////////////////////////////////////////
246    // IProCameraCallbacks implementation
247    ////////////////////////////////////////////////////////
248    virtual void        notifyCallback(int32_t msgType,
249                                       int32_t ext,
250                                       int32_t ext2);
251
252    virtual void        onLockStatusChanged(
253                                IProCameraCallbacks::LockStatus newLockStatus);
254
255    virtual void        onResultReceived(int32_t requestId,
256                                         camera_metadata* result);
257private:
258    ProCamera(int cameraId);
259
260    class ProFrameListener : public CpuConsumer::FrameAvailableListener {
261    public:
262        ProFrameListener(wp<ProCamera> camera, int streamID) {
263            mCamera = camera;
264            mStreamId = streamID;
265        }
266
267    protected:
268        virtual void onFrameAvailable(const BufferItem& /* item */) {
269            sp<ProCamera> c = mCamera.promote();
270            if (c.get() != NULL) {
271                c->onFrameAvailable(mStreamId);
272            }
273        }
274
275    private:
276        wp<ProCamera> mCamera;
277        int mStreamId;
278    };
279    friend class ProFrameListener;
280
281    struct StreamInfo
282    {
283        StreamInfo(int streamId) {
284            this->streamID = streamId;
285            cpuStream = false;
286            frameReady = 0;
287        }
288
289        StreamInfo() {
290            streamID = -1;
291            cpuStream = false;
292        }
293
294        int  streamID;
295        bool cpuStream;
296        sp<CpuConsumer> cpuConsumer;
297        bool synchronousMode;
298        sp<ProFrameListener> frameAvailableListener;
299        sp<Surface> stc;
300        int frameReady;
301    };
302
303    Condition mWaitCondition;
304    Mutex     mWaitMutex;
305    static const nsecs_t mWaitTimeout = 1000000000; // 1sec
306    KeyedVector<int, StreamInfo> mStreams;
307    bool mMetadataReady;
308    CameraMetadata mLatestMetadata;
309
310    void onFrameAvailable(int streamId);
311
312    StreamInfo& getStreamInfo(int streamId);
313
314    friend class CameraBase;
315};
316
317}; // namespace android
318
319#endif
320