1985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin/*
2985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * Copyright (C) 2013 The Android Open Source Project
3985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin *
4985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * you may not use this file except in compliance with the License.
6985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * You may obtain a copy of the License at
7985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin *
8985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin *
10985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * Unless required by applicable law or agreed to in writing, software
11985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * See the License for the specific language governing permissions and
14985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin * limitations under the License.
15985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin */
16985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
17985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#define LOG_TAG "ProCamera2Client"
18985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA
19985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin//#define LOG_NDEBUG 0
20985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
21985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#include <utils/Log.h>
22985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#include <utils/Trace.h>
23985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
24985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#include <cutils/properties.h>
25985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#include <gui/Surface.h>
26985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#include <gui/Surface.h>
277b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
287b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api_pro/ProCamera2Client.h"
297b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h"
30985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
31985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinnamespace android {
32985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinusing namespace camera2;
33985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
34985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin// Interface used by CameraService
35985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
36985fd30a10f6fec4293f071fd258c4726cff5a3dIgor MurashkinProCamera2Client::ProCamera2Client(const sp<CameraService>& cameraService,
3744cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   const sp<IProCameraCallbacks>& remoteCallback,
3844cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   const String16& clientPackageName,
3944cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   int cameraId,
4044cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   int cameraFacing,
4144cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   int clientPid,
4244cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   uid_t clientUid,
4344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                                   int servicePid) :
4444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
4544cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin                cameraId, cameraFacing, clientPid, clientUid, servicePid)
46985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin{
47985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
48985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGI("ProCamera %d: Opened", cameraId);
49985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
50985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    mExclusiveLock = false;
51985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
52985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
53985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::initialize(camera_module_t *module)
54985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin{
55985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
56985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    status_t res;
57985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
5844cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    res = Camera2ClientBase::initialize(module);
59985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (res != OK) {
6044cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin        return res;
61985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
62985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
63a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    String8 threadName;
647b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    mFrameProcessor = new FrameProcessorBase(mDevice);
6544cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    threadName = String8::format("PC2-%d-FrameProc", mCameraId);
66a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    mFrameProcessor->run(threadName.string());
67a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
68a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
69a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
70a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin                                      /*listener*/this);
71a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
72985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return OK;
73985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
74985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
75985fd30a10f6fec4293f071fd258c4726cff5a3dIgor MurashkinProCamera2Client::~ProCamera2Client() {
76985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
77985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
78985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::exclusiveTryLock() {
79985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
80985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("%s", __FUNCTION__);
81985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
8244cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
83985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
84985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
85bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return PERMISSION_DENIED;
86bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
87985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (!mExclusiveLock) {
88985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        mExclusiveLock = true;
89985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
90985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        if (mRemoteCallback != NULL) {
91985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin            mRemoteCallback->onLockStatusChanged(
92985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin                              IProCameraCallbacks::LOCK_ACQUIRED);
93985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        }
94985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
95985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        ALOGV("%s: exclusive lock acquired", __FUNCTION__);
96985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
97985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        return OK;
98985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
99985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
100985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    // TODO: have a PERMISSION_DENIED case for when someone else owns the lock
101985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
102985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    // don't allow recursive locking
103985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGW("%s: exclusive lock already exists - recursive locking is not"
104985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin          "allowed", __FUNCTION__);
105985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
106985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return ALREADY_EXISTS;
107985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
108985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
109985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::exclusiveLock() {
110985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
111985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("%s", __FUNCTION__);
112985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
11344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
114985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
115985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
116bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return PERMISSION_DENIED;
117bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
118985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    /**
119985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin     * TODO: this should asynchronously 'wait' until the lock becomes available
120985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin     * if another client already has an exclusive lock.
121985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin     *
122985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin     * once we have proper sharing support this will need to do
123985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin     * more than just return immediately
124985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin     */
125985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (!mExclusiveLock) {
126985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        mExclusiveLock = true;
127985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
128985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        if (mRemoteCallback != NULL) {
129985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin            mRemoteCallback->onLockStatusChanged(IProCameraCallbacks::LOCK_ACQUIRED);
130985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        }
131985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
132985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        ALOGV("%s: exclusive lock acquired", __FUNCTION__);
133985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
134985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        return OK;
135985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
136985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
137985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    // don't allow recursive locking
138985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGW("%s: exclusive lock already exists - recursive locking is not allowed"
139985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin                                                                , __FUNCTION__);
140985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return ALREADY_EXISTS;
141985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
142985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
143985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::exclusiveUnlock() {
144985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
145985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("%s", __FUNCTION__);
146985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
14744cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
148985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
149985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
150985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    // don't allow unlocking if we have no lock
151985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (!mExclusiveLock) {
152985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        ALOGW("%s: cannot unlock, no lock was held in the first place",
153985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin              __FUNCTION__);
154985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        return BAD_VALUE;
155985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
156985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
157985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    mExclusiveLock = false;
158985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (mRemoteCallback != NULL ) {
159985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        mRemoteCallback->onLockStatusChanged(
160985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin                                       IProCameraCallbacks::LOCK_RELEASED);
161985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
162985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("%s: exclusive lock released", __FUNCTION__);
163985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
164985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return OK;
165985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
166985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
167985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinbool ProCamera2Client::hasExclusiveLock() {
16844cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
169985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return mExclusiveLock;
170985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
171985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
172bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkinvoid ProCamera2Client::onExclusiveLockStolen() {
173bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("%s: ProClient lost exclusivity (id %d)",
174bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin          __FUNCTION__, mCameraId);
175bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
17644cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
177bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
178bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
179bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (mExclusiveLock && mRemoteCallback.get() != NULL) {
180bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        mRemoteCallback->onLockStatusChanged(
181bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin                                       IProCameraCallbacks::LOCK_STOLEN);
182bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
183bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
184bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    mExclusiveLock = false;
185bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
186bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    //TODO: we should not need to detach the device, merely reset it.
187bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    detachDevice();
188bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin}
189bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
190985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::submitRequest(camera_metadata_t* request,
191985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin                                         bool streaming) {
192985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
193985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("%s", __FUNCTION__);
194985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
19544cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
196bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
197bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
198bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
199985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (!mExclusiveLock) {
200985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        return PERMISSION_DENIED;
201985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
202985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
2033261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    CameraMetadata metadata(request);
2043261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
20503ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    if (!enforceRequestPermissions(metadata)) {
20603ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        return PERMISSION_DENIED;
20703ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    }
20803ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
2093261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if (streaming) {
2103261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin        return mDevice->setStreamingRequest(metadata);
2113261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    } else {
2123261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin        return mDevice->capture(metadata);
2133261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    }
2143261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
2153261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    // unreachable. thx gcc for a useless warning
216985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return OK;
217985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
218985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
219985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::cancelRequest(int requestId) {
2207b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    (void)requestId;
221985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ATRACE_CALL();
222985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("%s", __FUNCTION__);
223985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
22444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
225bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
226bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
227bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
228985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (!mExclusiveLock) {
229985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin        return PERMISSION_DENIED;
230985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    }
231985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
23244cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    // TODO: implement
233985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGE("%s: not fully implemented yet", __FUNCTION__);
2343261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    return INVALID_OPERATION;
235985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
236985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
237fa4cf9d310685b4c25877cba772ff7da84caf517Igor Murashkinstatus_t ProCamera2Client::deleteStream(int streamId) {
2383261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    ATRACE_CALL();
2393261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
240985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
2413261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    status_t res;
2423261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
2433261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
24444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
2453261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
246bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
2475835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    mDevice->clearStreamingRequest();
2485835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2495835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    status_t code;
2505835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if ((code = mDevice->waitUntilDrained()) != OK) {
2515835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__, code);
2525835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
2535835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2543261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    return mDevice->deleteStream(streamId);
255985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
256985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
257985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::createStream(int width, int height, int format,
25876f8b43909817179b317880202360863b8f976d0Igor Murashkin                      const sp<IGraphicBufferProducer>& bufferProducer,
2593261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin                      /*out*/
2603261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin                      int* streamId)
2613261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin{
2623261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if (streamId) {
2633261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin        *streamId = -1;
2643261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    }
265985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
2663261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    ATRACE_CALL();
2673261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
2683261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
2693261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    status_t res;
2703261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
2713261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
27244cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
2733261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin
274bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
275bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
27676f8b43909817179b317880202360863b8f976d0Igor Murashkin    sp<IBinder> binder;
27776f8b43909817179b317880202360863b8f976d0Igor Murashkin    sp<ANativeWindow> window;
27876f8b43909817179b317880202360863b8f976d0Igor Murashkin    if (bufferProducer != 0) {
27976f8b43909817179b317880202360863b8f976d0Igor Murashkin        binder = bufferProducer->asBinder();
28076f8b43909817179b317880202360863b8f976d0Igor Murashkin        window = new Surface(bufferProducer);
28176f8b43909817179b317880202360863b8f976d0Igor Murashkin    }
28276f8b43909817179b317880202360863b8f976d0Igor Murashkin
28328c9b6f298134624cb52b1af4ed8716dddb983d3Zhijun He    return mDevice->createStream(window, width, height, format,
28476f8b43909817179b317880202360863b8f976d0Igor Murashkin                                 streamId);
285985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
286985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
2873261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin// Create a request object from a template.
2883261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin// -- Caller owns the newly allocated metadata
289985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::createDefaultRequest(int templateId,
2903261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin                             /*out*/
2913261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin                              camera_metadata** request)
2923261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin{
2933261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    ATRACE_CALL();
2943261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
295985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
2963261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if (request) {
2973261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin        *request = NULL;
2983261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    }
299985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
3003261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    status_t res;
3013261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
302985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
30344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
304985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
305bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
306bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
3073261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    CameraMetadata metadata;
3083261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK) {
3093261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin        *request = metadata.release();
3103261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    }
311985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
3123261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin    return res;
3133261fd3f1d8f798fab2f1b3efaa92d5a35cd42e7Igor Murashkin}
314985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
3157b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkinstatus_t ProCamera2Client::getCameraInfo(int cameraId,
3167b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin                                         /*out*/
3177b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin                                         camera_metadata** info)
3187b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin{
3197b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    if (cameraId != mCameraId) {
3207b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin        return INVALID_OPERATION;
3217b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    }
3227b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
32344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
324bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
325bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
326bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
3277b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    CameraMetadata deviceInfo = mDevice->info();
3287b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    *info = deviceInfo.release();
3297b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
3307b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    return OK;
3317b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin}
3327b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
333985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkinstatus_t ProCamera2Client::dump(int fd, const Vector<String16>& args) {
334985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    String8 result;
335985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n",
336985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin            mCameraId,
337985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin            getRemoteCallback()->asBinder().get(),
338985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin            mClientPid);
33967489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    result.append("  State:\n");
34067489d2f5668441a36cb1f1157e80ec8684023bfEino-Ville Talvala    write(fd, result.string(), result.size());
341985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
342985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    // TODO: print dynamic/request section from most recent requests
343a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    mFrameProcessor->dump(fd, args);
34444cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    return dumpDevice(fd, args);
345985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
346985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
347985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin// IProCameraUser interface
348985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
349bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkinvoid ProCamera2Client::detachDevice() {
350985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (mDevice == 0) return;
351985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
352bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    ALOGV("Camera %d: Stopping processors", mCameraId);
353bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
354a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
355a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
356a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin                                    /*listener*/this);
357a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    mFrameProcessor->requestExit();
358985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("Camera %d: Waiting for threads", mCameraId);
359a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    mFrameProcessor->join();
360985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    ALOGV("Camera %d: Disconnecting device", mCameraId);
361985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
362bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
363bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    {
364bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        mDevice->clearStreamingRequest();
365bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
366bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        status_t code;
367bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        if ((code = mDevice->waitUntilDrained()) != OK) {
368bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
369bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin                  code);
370bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        }
371bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
372bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin
37344cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Camera2ClientBase::detachDevice();
374985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin}
375985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
376cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weivoid ProCamera2Client::onResultAvailable(const CaptureResult& result) {
377a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    ATRACE_CALL();
378a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    ALOGV("%s", __FUNCTION__);
379a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
38044cfcf00b9008c1c04f4c8277c6c06af039fd976Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
381a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
382a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
383a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    if (mRemoteCallback != NULL) {
384cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        CameraMetadata tmp(result.mMetadata);
385a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        camera_metadata_t* meta = tmp.release();
386a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        ALOGV("%s: meta = %p ", __FUNCTION__, meta);
387cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        mRemoteCallback->onResultReceived(result.mResultExtras.requestId, meta);
388a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        tmp.acquire(meta);
389a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    }
390a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin}
391a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
39203ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkinbool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {
39303ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
39403ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    const int pid = IPCThreadState::self()->getCallingPid();
39503ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    const int selfPid = getpid();
39603ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    camera_metadata_entry_t entry;
39703ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
39803ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    /**
39903ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin     * Mixin default important security values
40003ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin     * - android.led.transmit = defaulted ON
40103ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin     */
40203ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    CameraMetadata staticInfo = mDevice->info();
40303ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
40403ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    for(size_t i = 0; i < entry.count; ++i) {
40503ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        uint8_t led = entry.data.u8[i];
40603ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
40703ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        switch(led) {
40803ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
40903ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
41003ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
41103ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                    metadata.update(ANDROID_LED_TRANSMIT,
41203ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                                    &transmitDefault, 1);
41303ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                }
41403ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                break;
41503ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin            }
41603ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        }
41703ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    }
41803ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
41903ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    // We can do anything!
42003ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    if (pid == selfPid) {
42103ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        return true;
42203ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    }
42303ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
42403ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    /**
42503ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin     * Permission check special fields in the request
42603ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
42703ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin     */
42803ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    entry = metadata.find(ANDROID_LED_TRANSMIT);
42903ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
43003ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        String16 permissionString =
43103ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
43203ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        if (!checkCallingPermission(permissionString)) {
43303ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin            const int uid = IPCThreadState::self()->getCallingUid();
43403ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin            ALOGE("Permission Denial: "
43503ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
43603ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin            return false;
43703ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin        }
43803ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    }
43903ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
44003ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin    return true;
44103ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin}
44203ac850527ffb90348dcdaad95caceb97649fd6bIgor Murashkin
443985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin} // namespace android
444