ProCamera2Client.cpp revision cb0652e5a850b2fcd919e977247e87239efaf70e
1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl/*
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * Copyright (C) 2013 The Android Open Source Project
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl *
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * Licensed under the Apache License, Version 2.0 (the "License");
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * you may not use this file except in compliance with the License.
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * You may obtain a copy of the License at
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl *
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl *      http://www.apache.org/licenses/LICENSE-2.0
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl *
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * Unless required by applicable law or agreed to in writing, software
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * distributed under the License is distributed on an "AS IS" BASIS,
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * See the License for the specific language governing permissions and
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl * limitations under the License.
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl */
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LOG_TAG "ProCamera2Client"
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define ATRACE_TAG ATRACE_TAG_CAMERA
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//#define LOG_NDEBUG 0
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include <utils/Log.h>
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include <utils/Trace.h>
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include <cutils/properties.h>
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include <gui/Surface.h>
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include <gui/Surface.h>
27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "api_pro/ProCamera2Client.h"
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "common/CameraDeviceBase.h"
30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace android {
32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlusing namespace camera2;
33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Interface used by CameraService
35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   const sp<IProCameraCallbacks>& remoteCallback,
38ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                                   const String16& clientPackageName,
39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   int cameraId,
40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                   int cameraFacing,
41ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                                   int clientPid,
42ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                                   uid_t clientUid,
43ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                                   int servicePid) :
44ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
45ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                cameraId, cameraFacing, clientPid, clientUid, servicePid)
46ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl{
47ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ATRACE_CALL();
48ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ALOGI("ProCamera %d: Opened", cameraId);
49ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
50ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    mExclusiveLock = false;
51ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl}
52ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
53ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatus_t ProCamera2Client::initialize(camera_module_t *module)
54ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl{
55ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ATRACE_CALL();
56ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    status_t res;
57ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
58ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    res = Camera2ClientBase::initialize(module);
59ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if (res != OK) {
60ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        return res;
61ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    }
62ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    String8 threadName;
64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mFrameProcessor = new FrameProcessorBase(mDevice);
65ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    threadName = String8::format("PC2-%d-FrameProc", mCameraId);
66ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    mFrameProcessor->run(threadName.string());
67ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
70ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                                      /*listener*/this);
71ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
72ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return OK;
73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
74ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
75ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlProCamera2Client::~ProCamera2Client() {
76ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl}
77ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
78ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatus_t ProCamera2Client::exclusiveTryLock() {
79ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ATRACE_CALL();
80ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ALOGV("%s", __FUNCTION__);
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Mutex::Autolock icl(mBinderSerializationLock);
83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
84ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
85ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if (!mDevice.get()) return PERMISSION_DENIED;
86ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
87ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if (!mExclusiveLock) {
88ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        mExclusiveLock = true;
89ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        if (mRemoteCallback != NULL) {
91ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl            mRemoteCallback->onLockStatusChanged(
92ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                              IProCameraCallbacks::LOCK_ACQUIRED);
93ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        }
94ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
95ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        ALOGV("%s: exclusive lock acquired", __FUNCTION__);
96ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
97ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        return OK;
98ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    }
99ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
100ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
101ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
102ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    // don't allow recursive locking
103ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ALOGW("%s: exclusive lock already exists - recursive locking is not"
104ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl          "allowed", __FUNCTION__);
105ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
106ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return ALREADY_EXISTS;
107ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl}
108ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
109ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatus_t ProCamera2Client::exclusiveLock() {
110ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    ATRACE_CALL();
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ALOGV("%s", __FUNCTION__);
112ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
113ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    Mutex::Autolock icl(mBinderSerializationLock);
114ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
115ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
116ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if (!mDevice.get()) return PERMISSION_DENIED;
117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    /**
119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl     * TODO: this should asynchronously 'wait' until the lock becomes available
120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl     * if another client already has an exclusive lock.
121ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl     *
122ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl     * once we have proper sharing support this will need to do
123ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl     * more than just return immediately
124ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl     */
125ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if (!mExclusiveLock) {
126ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        mExclusiveLock = true;
127ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
128ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        if (mRemoteCallback != NULL) {
129ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl            mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
130ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        }
131ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
132ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        ALOGV("%s: exclusive lock acquired", __FUNCTION__);
133ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
134ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        return OK;
135ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    }
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    // don't allow recursive locking
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
139ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                                                                , __FUNCTION__);
140ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return ALREADY_EXISTS;
141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
143ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlstatus_t ProCamera2Client::exclusiveUnlock() {
144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ATRACE_CALL();
145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ALOGV("%s", __FUNCTION__);
146ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
147ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    Mutex::Autolock icl(mBinderSerializationLock);
148ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
149ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
150ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    // don't allow unlocking if we have no lock
151ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if (!mExclusiveLock) {
152ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        ALOGW("%s: cannot unlock, no lock was held in the first place",
153ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              __FUNCTION__);
154ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        return BAD_VALUE;
155ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    }
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
157ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    mExclusiveLock = false;
158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (mRemoteCallback != NULL ) {
159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        mRemoteCallback->onLockStatusChanged(
160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                       IProCameraCallbacks::LOCK_RELEASED);
161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ALOGV("%s: exclusive lock released", __FUNCTION__);
163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
164ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return OK;
165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
167ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlbool ProCamera2Client::hasExclusiveLock() {
168ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    Mutex::Autolock icl(mBinderSerializationLock);
169ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    return mExclusiveLock;
170ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl}
171ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
172ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlvoid ProCamera2Client::onExclusiveLockStolen() {
173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ALOGV("%s: ProClient lost exclusivity (id %d)",
174ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl          __FUNCTION__, mCameraId);
175ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    Mutex::Autolock icl(mBinderSerializationLock);
177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
178ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (mExclusiveLock && mRemoteCallback.get() != NULL) {
180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        mRemoteCallback->onLockStatusChanged(
181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                       IProCameraCallbacks::LOCK_STOLEN);
182ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    }
183ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    mExclusiveLock = false;
185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
186ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    //TODO: we should not need to detach the device, merely reset it.
187ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    detachDevice();
188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatus_t ProCamera2Client::submitRequest(camera_metadata_t* request,
191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                         bool streaming) {
192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ATRACE_CALL();
193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ALOGV("%s", __FUNCTION__);
194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
195    Mutex::Autolock icl(mBinderSerializationLock);
196
197    if (!mDevice.get()) return DEAD_OBJECT;
198
199    if (!mExclusiveLock) {
200        return PERMISSION_DENIED;
201    }
202
203    CameraMetadata metadata(request);
204
205    if (!enforceRequestPermissions(metadata)) {
206        return PERMISSION_DENIED;
207    }
208
209    if (streaming) {
210        return mDevice->setStreamingRequest(metadata);
211    } else {
212        return mDevice->capture(metadata);
213    }
214
215    // unreachable. thx gcc for a useless warning
216    return OK;
217}
218
219status_t ProCamera2Client::cancelRequest(int requestId) {
220    (void)requestId;
221    ATRACE_CALL();
222    ALOGV("%s", __FUNCTION__);
223
224    Mutex::Autolock icl(mBinderSerializationLock);
225
226    if (!mDevice.get()) return DEAD_OBJECT;
227
228    if (!mExclusiveLock) {
229        return PERMISSION_DENIED;
230    }
231
232    // TODO: implement
233    ALOGE("%s: not fully implemented yet", __FUNCTION__);
234    return INVALID_OPERATION;
235}
236
237status_t ProCamera2Client::deleteStream(int streamId) {
238    ATRACE_CALL();
239    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
240
241    status_t res;
242    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
243
244    Mutex::Autolock icl(mBinderSerializationLock);
245
246    if (!mDevice.get()) return DEAD_OBJECT;
247    mDevice->clearStreamingRequest();
248
249    status_t code;
250    if ((code = mDevice->waitUntilDrained()) != OK) {
251        ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code);
252    }
253
254    return mDevice->deleteStream(streamId);
255}
256
257status_t ProCamera2Client::createStream(int width, int height, int format,
258                      const sp<IGraphicBufferProducer>& bufferProducer,
259                      /*out*/
260                      int* streamId)
261{
262    if (streamId) {
263        *streamId = -1;
264    }
265
266    ATRACE_CALL();
267    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
268
269    status_t res;
270    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
271
272    Mutex::Autolock icl(mBinderSerializationLock);
273
274    if (!mDevice.get()) return DEAD_OBJECT;
275
276    sp<IBinder> binder;
277    sp<ANativeWindow> window;
278    if (bufferProducer != 0) {
279        binder = bufferProducer->asBinder();
280        window = new Surface(bufferProducer);
281    }
282
283    return mDevice->createStream(window, width, height, format, /*size*/1,
284                                 streamId);
285}
286
287// Create a request object from a template.
288// -- Caller owns the newly allocated metadata
289status_t ProCamera2Client::createDefaultRequest(int templateId,
290                             /*out*/
291                              camera_metadata** request)
292{
293    ATRACE_CALL();
294    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
295
296    if (request) {
297        *request = NULL;
298    }
299
300    status_t res;
301    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
302
303    Mutex::Autolock icl(mBinderSerializationLock);
304
305    if (!mDevice.get()) return DEAD_OBJECT;
306
307    CameraMetadata metadata;
308    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) {
309        *request = metadata.release();
310    }
311
312    return res;
313}
314
315status_t ProCamera2Client::getCameraInfo(int cameraId,
316                                         /*out*/
317                                         camera_metadata** info)
318{
319    if (cameraId != mCameraId) {
320        return INVALID_OPERATION;
321    }
322
323    Mutex::Autolock icl(mBinderSerializationLock);
324
325    if (!mDevice.get()) return DEAD_OBJECT;
326
327    CameraMetadata deviceInfo = mDevice->info();
328    *info = deviceInfo.release();
329
330    return OK;
331}
332
333status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) {
334    String8 result;
335    result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n",
336            mCameraId,
337            getRemoteCallback()->asBinder().get(),
338            mClientPid);
339    result.append("  State: ");
340
341    // TODO: print dynamic/request section from most recent requests
342    mFrameProcessor->dump(fd, args);
343
344    return dumpDevice(fd, args);
345}
346
347// IProCameraUser interface
348
349void ProCamera2Client::detachDevice() {
350    if (mDevice == 0) return;
351
352    ALOGV("Camera %d: Stopping processors", mCameraId);
353
354    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
355                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
356                                    /*listener*/this);
357    mFrameProcessor->requestExit();
358    ALOGV("Camera %d: Waiting for threads", mCameraId);
359    mFrameProcessor->join();
360    ALOGV("Camera %d: Disconnecting device", mCameraId);
361
362    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
363    {
364        mDevice->clearStreamingRequest();
365
366        status_t code;
367        if ((code = mDevice->waitUntilDrained()) != OK) {
368            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
369                  code);
370        }
371    }
372
373    Camera2ClientBase::detachDevice();
374}
375
376void ProCamera2Client::onResultAvailable(const CaptureResult& result) {
377    ATRACE_CALL();
378    ALOGV("%s", __FUNCTION__);
379
380    Mutex::Autolock icl(mBinderSerializationLock);
381    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
382
383    if (mRemoteCallback != NULL) {
384        CameraMetadata tmp(result.mMetadata);
385        camera_metadata_t* meta = tmp.release();
386        ALOGV("%s: meta = %p ", __FUNCTION__, meta);
387        mRemoteCallback->onResultReceived(result.mResultExtras.requestId, meta);
388        tmp.acquire(meta);
389    }
390}
391
392bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {
393
394    const int pid = IPCThreadState::self()->getCallingPid();
395    const int selfPid = getpid();
396    camera_metadata_entry_t entry;
397
398    /**
399     * Mixin default important security values
400     * - android.led.transmit = defaulted ON
401     */
402    CameraMetadata staticInfo = mDevice->info();
403    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
404    for(size_t i = 0; i < entry.count; ++i) {
405        uint8_t led = entry.data.u8[i];
406
407        switch(led) {
408            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
409                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
410                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
411                    metadata.update(ANDROID_LED_TRANSMIT,
412                                    &transmitDefault, 1);
413                }
414                break;
415            }
416        }
417    }
418
419    // We can do anything!
420    if (pid == selfPid) {
421        return true;
422    }
423
424    /**
425     * Permission check special fields in the request
426     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
427     */
428    entry = metadata.find(ANDROID_LED_TRANSMIT);
429    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
430        String16 permissionString =
431            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
432        if (!checkCallingPermission(permissionString)) {
433            const int uid = IPCThreadState::self()->getCallingUid();
434            ALOGE("Permission Denial: "
435                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
436            return false;
437        }
438    }
439
440    return true;
441}
442
443} // namespace android
444