CameraDeviceClient.cpp revision 184dfe4ea5e2ba33951bed2b1366007aee0ce3da
1e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin/*
2e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Copyright (C) 2013 The Android Open Source Project
3e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *
4e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * you may not use this file except in compliance with the License.
6e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * You may obtain a copy of the License at
7e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *
8e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin *
10e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * Unless required by applicable law or agreed to in writing, software
11e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * See the License for the specific language governing permissions and
14e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin * limitations under the License.
15e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin */
16e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
17e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#define LOG_TAG "CameraDeviceClient"
18e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA
19e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// #define LOG_NDEBUG 0
20e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
217b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include <cutils/properties.h>
22e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <utils/Log.h>
23e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <utils/Trace.h>
24e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin#include <gui/Surface.h>
257b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include <camera/camera2/CaptureRequest.h>
267b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
277b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "common/CameraDeviceBase.h"
287b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "api2/CameraDeviceClient.h"
297b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
307b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
31e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
32e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinnamespace android {
33e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinusing namespace camera2;
34e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
35e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClientBase::CameraDeviceClientBase(
36e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const sp<CameraService>& cameraService,
37e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const sp<ICameraDeviceCallbacks>& remoteCallback,
38e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        const String16& clientPackageName,
39e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int cameraId,
40e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int cameraFacing,
41e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int clientPid,
42e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        uid_t clientUid,
43e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int servicePid) :
44e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    BasicClient(cameraService, remoteCallback->asBinder(), clientPackageName,
45e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                cameraId, cameraFacing, clientPid, clientUid, servicePid),
46e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mRemoteCallback(remoteCallback) {
47e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
48e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
49e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Interface used by CameraService
50e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
51e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
52e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   const sp<ICameraDeviceCallbacks>& remoteCallback,
53e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   const String16& clientPackageName,
54e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int cameraId,
55e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int cameraFacing,
56e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int clientPid,
57e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   uid_t clientUid,
58e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                   int servicePid) :
59e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
60e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                cameraId, cameraFacing, clientPid, clientUid, servicePid),
61e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mRequestIdCounter(0) {
62e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
63e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
64e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGI("CameraDeviceClient %d: Opened", cameraId);
65e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
66e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
67e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::initialize(camera_module_t *module)
68e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
69e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
70e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
71e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
72e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = Camera2ClientBase::initialize(module);
73e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res != OK) {
74e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
75e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
76e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
77e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    String8 threadName;
787b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    mFrameProcessor = new FrameProcessorBase(mDevice);
79e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    threadName = String8::format("CDU-%d-FrameProc", mCameraId);
80e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->run(threadName.string());
81e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
82e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
83e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
84184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala                                      /*listener*/this,
85184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala                                      /*quirkSendPartials*/true);
86e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
87e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return OK;
88e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
89e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
90e7ee7637747371635a85fedd24d2190bb1f38651Igor MurashkinCameraDeviceClient::~CameraDeviceClient() {
91e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
92e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
93e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
94e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                         bool streaming) {
95e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
96e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
97e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
98e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
99e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
100e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
101e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
102e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
103e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
104e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
105e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
106e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (request == 0) {
107e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
108e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId);
109e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
110e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
111e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
112e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata metadata(request->mMetadata);
113e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
114e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (metadata.isEmpty()) {
115e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
116e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin               __FUNCTION__, mCameraId);
117e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
118e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } else if (request->mSurfaceList.size() == 0) {
119e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Requests must have at least one surface target. "
120e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              "Rejecting request.", __FUNCTION__, mCameraId);
121e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
122e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
123e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
124e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!enforceRequestPermissions(metadata)) {
125e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        // Callee logs
126e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return PERMISSION_DENIED;
127e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
128e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
129e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
130e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Write in the output stream IDs which we calculate from
131e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * the capture request's list of surface targets
132e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
133d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He    Vector<int32_t> outputStreamIds;
134e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    outputStreamIds.setCapacity(request->mSurfaceList.size());
135e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
136e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        sp<Surface> surface = request->mSurfaceList[i];
137e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
138e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (surface == 0) continue;
139e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
140e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
141e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int idx = mStreamMap.indexOfKey(gbp->asBinder());
142e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
143e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        // Trying to submit request with surface that wasn't created
144e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (idx == NAME_NOT_FOUND) {
145e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
146e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  " we have not called createStream on",
147e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  __FUNCTION__, mCameraId);
148e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            return BAD_VALUE;
149e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
150e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
151e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        int streamId = mStreamMap.valueAt(idx);
152e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        outputStreamIds.push_back(streamId);
153e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Appending output stream %d to request",
154e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, streamId);
155e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
156e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
157e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
158e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                    outputStreamIds.size());
159e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
160e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    int32_t requestId = mRequestIdCounter++;
161e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
162e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s: Camera %d: Submitting request with ID %d",
163e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin          __FUNCTION__, mCameraId, requestId);
164e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
165e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (streaming) {
166e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        res = mDevice->setStreamingRequest(metadata);
167e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (res != OK) {
168e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("%s: Camera %d:  Got error %d after trying to set streaming "
169e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  "request", __FUNCTION__, mCameraId, res);
170e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        } else {
171fe0799e8f1c5db22df3bafdfb9ec995f5494d260Zhijun He            mStreamingRequestList.push_back(requestId);
172e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
173e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } else {
174e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        res = mDevice->capture(metadata);
175e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (res != OK) {
176e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("%s: Camera %d: Got error %d after trying to set capture",
177e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  __FUNCTION__, mCameraId, res);
178e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
179e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
180e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
181e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
182e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == OK) {
183e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return requestId;
184e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
185e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
186e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
187e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
188e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
189e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::cancelRequest(int requestId) {
190e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
191e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
192e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
193e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
194e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
195e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
196e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
197e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
198e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
199e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
200e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
201e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Vector<int>::iterator it, end;
202e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
203e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin         it != end; ++it) {
204e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (*it == requestId) {
205e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            break;
206e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
207e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
208e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
209e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (it == end) {
210e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera%d: Did not find request id %d in list of streaming "
211e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              "requests", __FUNCTION__, mCameraId, requestId);
212e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
213e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
214e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
215e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = mDevice->clearStreamingRequest();
216e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
217e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == OK) {
218e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Successfully cleared streaming request",
219e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId);
220e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mStreamingRequestList.erase(it);
221e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
222e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
223e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
224e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
225e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
226e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::deleteStream(int streamId) {
227e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
228e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
229e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
230e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
231e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
232e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
233e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
234e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
235e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
236e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
237e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Guard against trying to delete non-created streams
238e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ssize_t index = NAME_NOT_FOUND;
239e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for (size_t i = 0; i < mStreamMap.size(); ++i) {
240e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (streamId == mStreamMap.valueAt(i)) {
241e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            index = i;
242e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            break;
243e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
244e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
245e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
246e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (index == NAME_NOT_FOUND) {
247e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream "
248e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              "created yet", __FUNCTION__, mCameraId, streamId);
249e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return BAD_VALUE;
250e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
251e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
252e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Also returns BAD_VALUE if stream ID was not valid
253e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    res = mDevice->deleteStream(streamId);
254e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
255e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == BAD_VALUE) {
256e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Unexpected BAD_VALUE when deleting stream, but we"
257e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              " already checked and the stream ID (%d) should be valid.",
258e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, streamId);
259e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    } else if (res == OK) {
260e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mStreamMap.removeItemsAt(index);
261e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
262e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Successfully deleted stream ID (%d)",
263e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, streamId);
264e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
265e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
266e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
267e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
268e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
269e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::createStream(int width, int height, int format,
270e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                      const sp<IGraphicBufferProducer>& bufferProducer)
271e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
272e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
273e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (w = %d, h = %d, f = 0x%x)", __FUNCTION__, width, height, format);
274e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
275e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
276e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
277e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
278e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
279e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
280e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
281e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
282e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // Don't create multiple streams for the same target surface
283e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    {
284e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
285e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (index != NAME_NOT_FOUND) {
286e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
287e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  "(ID %d)",
288e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  __FUNCTION__, mCameraId, index);
289e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            return ALREADY_EXISTS;
290e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
291e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
292e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
2931da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // HACK b/10949105
2941da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // Query consumer usage bits to set async operation mode for
2951da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    // GLConsumer using controlledByApp parameter.
2961da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    bool useAsync = false;
2971da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    int32_t consumerUsage;
2981da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    if ((res = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
2991da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala            &consumerUsage)) != OK) {
3001da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        ALOGE("%s: Camera %d: Failed to query consumer usage", __FUNCTION__,
3011da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala              mCameraId);
3021da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        return res;
3031da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    }
3041da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
3051da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
3061da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala                __FUNCTION__, mCameraId);
3071da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        useAsync = true;
3081da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala    }
3091da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala
310e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    sp<IBinder> binder;
311e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    sp<ANativeWindow> anw;
312e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (bufferProducer != 0) {
313e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        binder = bufferProducer->asBinder();
3141da3b602130d71ac3bff1a1fdecdc5e0d7b9d701Eino-Ville Talvala        anw = new Surface(bufferProducer, useAsync);
315e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
316e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
317e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: remove w,h,f since we are ignoring them
318e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
319e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ((res = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, &width)) != OK) {
320e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Failed to query Surface width", __FUNCTION__,
321e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              mCameraId);
322e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
323e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
324e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ((res = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, &height)) != OK) {
325e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Failed to query Surface height", __FUNCTION__,
326e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              mCameraId);
327e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
328e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
329e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ((res = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &format)) != OK) {
330e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGE("%s: Camera %d: Failed to query Surface format", __FUNCTION__,
331e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              mCameraId);
332e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return res;
333e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
334e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
335e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // FIXME: remove this override since the default format should be
336e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    //       IMPLEMENTATION_DEFINED. b/9487482
3371581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin    if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
3381581101ce2a8c1b8d0b07b643ad891595221d781Igor Murashkin        format <= HAL_PIXEL_FORMAT_BGRA_8888) {
339e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED",
340e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, format);
341e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
342e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
343e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
344e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: add startConfigure/stopConfigure call to CameraDeviceBase
345e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // this will make it so Camera3Device doesn't call configure_streams
346e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // after each call, but only once we are done with all.
347e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
348e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    int streamId = -1;
349c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala    if (format == HAL_PIXEL_FORMAT_BLOB) {
350c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        // JPEG buffers need to be sized for maximum possible compressed size
351c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        CameraMetadata staticInfo = mDevice->info();
352c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        camera_metadata_entry_t entry = staticInfo.find(ANDROID_JPEG_MAX_SIZE);
353c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        if (entry.count == 0) {
354c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala            ALOGE("%s: Camera %d: Can't find maximum JPEG size in "
355c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala                    "static metadata!", __FUNCTION__, mCameraId);
356c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala            return INVALID_OPERATION;
357c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        }
358c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        int32_t maxJpegSize = entry.data.i32[0];
359c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        res = mDevice->createStream(anw, width, height, format, maxJpegSize,
360c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala                &streamId);
361c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala    } else {
362c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        // All other streams are a known size
363c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala        res = mDevice->createStream(anw, width, height, format, /*size*/0,
364c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala                &streamId);
365c7ba4a5c938d191bf0e477fc9b9aa4f0cba986efEino-Ville Talvala    }
366e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
367e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (res == OK) {
368e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mStreamMap.add(bufferProducer->asBinder(), streamId);
369e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
370e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
371e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin              __FUNCTION__, mCameraId, streamId);
372f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
373f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        /**
374f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin         * Set the stream transform flags to automatically
375f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin         * rotate the camera stream for preview use cases.
376f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin         */
377f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        int32_t transform = 0;
378f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        res = getRotationTransformLocked(&transform);
379f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
380f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        if (res != OK) {
381f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            // Error logged by getRotationTransformLocked.
382f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            return res;
383f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        }
384f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
385f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        res = mDevice->setStreamTransform(streamId, transform);
386f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        if (res != OK) {
387f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            ALOGE("%s: Failed to set stream transform (stream id %d)",
388f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin                  __FUNCTION__, streamId);
389f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            return res;
390f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        }
391f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
392e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return streamId;
393e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
394e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
395e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
396e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
397e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
398e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// Create a request object from a template.
399e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::createDefaultRequest(int templateId,
400e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                                  /*out*/
401e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                                  CameraMetadata* request)
402e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
403e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
404e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
405e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
406e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res;
407e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
408e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
409e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
410e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
411e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
412e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
413e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata metadata;
414e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
415e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        request != NULL) {
416e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
417e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        request->swap(metadata);
418e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
419e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
420e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
421e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
422e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
423099b457f3203fa51387e21bd450495abb973ab31Igor Murashkinstatus_t CameraDeviceClient::getCameraInfo(/*out*/CameraMetadata* info)
424e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin{
425e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
426e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
427e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
428e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    status_t res = OK;
429e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
430e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
431e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
432e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Mutex::Autolock icl(mBinderSerializationLock);
433e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
434e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (!mDevice.get()) return DEAD_OBJECT;
435e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
436099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin    if (info != NULL) {
437099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin        *info = mDevice->info(); // static camera metadata
438099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin        // TODO: merge with device-specific camera metadata
439099b457f3203fa51387e21bd450495abb973ab31Igor Murashkin    }
440e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
441e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return res;
442e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
443e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
4442ab500c632569e2f131a1a2288459933da70c4eeZhijun Hestatus_t CameraDeviceClient::waitUntilIdle()
4452ab500c632569e2f131a1a2288459933da70c4eeZhijun He{
4462ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ATRACE_CALL();
4472ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ALOGV("%s", __FUNCTION__);
4482ab500c632569e2f131a1a2288459933da70c4eeZhijun He
4492ab500c632569e2f131a1a2288459933da70c4eeZhijun He    status_t res = OK;
4502ab500c632569e2f131a1a2288459933da70c4eeZhijun He    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
4512ab500c632569e2f131a1a2288459933da70c4eeZhijun He
4522ab500c632569e2f131a1a2288459933da70c4eeZhijun He    Mutex::Autolock icl(mBinderSerializationLock);
4532ab500c632569e2f131a1a2288459933da70c4eeZhijun He
4542ab500c632569e2f131a1a2288459933da70c4eeZhijun He    if (!mDevice.get()) return DEAD_OBJECT;
4552ab500c632569e2f131a1a2288459933da70c4eeZhijun He
4562ab500c632569e2f131a1a2288459933da70c4eeZhijun He    // FIXME: Also need check repeating burst.
4572ab500c632569e2f131a1a2288459933da70c4eeZhijun He    if (!mStreamingRequestList.isEmpty()) {
4582ab500c632569e2f131a1a2288459933da70c4eeZhijun He        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
4592ab500c632569e2f131a1a2288459933da70c4eeZhijun He              __FUNCTION__, mCameraId);
4602ab500c632569e2f131a1a2288459933da70c4eeZhijun He        return INVALID_OPERATION;
4612ab500c632569e2f131a1a2288459933da70c4eeZhijun He    }
4622ab500c632569e2f131a1a2288459933da70c4eeZhijun He    res = mDevice->waitUntilDrained();
4632ab500c632569e2f131a1a2288459933da70c4eeZhijun He    ALOGV("%s Done", __FUNCTION__);
4642ab500c632569e2f131a1a2288459933da70c4eeZhijun He
4652ab500c632569e2f131a1a2288459933da70c4eeZhijun He    return res;
4662ab500c632569e2f131a1a2288459933da70c4eeZhijun He}
4672ab500c632569e2f131a1a2288459933da70c4eeZhijun He
468abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvalastatus_t CameraDeviceClient::flush() {
469abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ATRACE_CALL();
470abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ALOGV("%s", __FUNCTION__);
471abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
472abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    status_t res = OK;
473abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
474abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
475abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    Mutex::Autolock icl(mBinderSerializationLock);
476abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
477abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    if (!mDevice.get()) return DEAD_OBJECT;
478abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
479abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    return mDevice->flush();
480abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala}
481abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
482e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinstatus_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
483e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    String8 result;
484e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
485e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            mCameraId,
486e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            getRemoteCallback()->asBinder().get(),
487e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            mClientPid);
488e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    result.append("  State: ");
489e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
490e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // TODO: print dynamic/request section from most recent requests
491e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->dump(fd, args);
492e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
493e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return dumpDevice(fd, args);
494e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
495e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
496f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
497f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::notifyError() {
498f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
499f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
500f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
501f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
502f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        remoteCb->onDeviceError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE);
503f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
504f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
505f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
506f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::notifyIdle() {
507f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
508f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
509f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
510f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
511f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        remoteCb->onDeviceIdle();
512f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
513f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
514f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
515f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::notifyShutter(int requestId,
516f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        nsecs_t timestamp) {
517f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Thread safe. Don't bother locking.
518f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
519f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (remoteCb != 0) {
520f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        remoteCb->onCaptureStarted(requestId, timestamp);
521f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
522f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
523f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
524e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: refactor the code below this with IProCameraUser.
525e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// it's 100% copy-pasted, so lets not change it right now to make it easier.
526e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
527e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinvoid CameraDeviceClient::detachDevice() {
528e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (mDevice == 0) return;
529e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
530e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Stopping processors", mCameraId);
531e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
532e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->removeListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
533e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    FRAME_PROCESSOR_LISTENER_MAX_ID,
534e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    /*listener*/this);
535e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->requestExit();
536e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Waiting for threads", mCameraId);
537e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    mFrameProcessor->join();
538e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("Camera %d: Disconnecting device", mCameraId);
539e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
540e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // WORKAROUND: HAL refuses to disconnect while there's streams in flight
541e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    {
542e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        mDevice->clearStreamingRequest();
543e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
544e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        status_t code;
545e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if ((code = mDevice->waitUntilDrained()) != OK) {
546e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
547e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  code);
548e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
549e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
550e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
551e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    Camera2ClientBase::detachDevice();
552e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
553e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
554e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin/** Device-related methods */
555f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid CameraDeviceClient::onFrameAvailable(int32_t requestId,
556f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        const CameraMetadata& frame) {
557e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ATRACE_CALL();
558e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    ALOGV("%s", __FUNCTION__);
559e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
5604fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    // Thread-safe. No lock necessary.
5614fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
5624fb55c15da1a563ab925914a0f493a3dc80495a3Igor Murashkin    if (remoteCb != NULL) {
563e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        ALOGV("%s: frame = %p ", __FUNCTION__, &frame);
564f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        remoteCb->onResultReceived(requestId, frame);
565e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
566e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
567e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
568e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin// TODO: move to Camera2ClientBase
569e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkinbool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
570e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
571e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const int pid = IPCThreadState::self()->getCallingPid();
572e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    const int selfPid = getpid();
573e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    camera_metadata_entry_t entry;
574e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
575e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
576e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Mixin default important security values
577e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * - android.led.transmit = defaulted ON
578e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
579e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    CameraMetadata staticInfo = mDevice->info();
580e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
581e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    for(size_t i = 0; i < entry.count; ++i) {
582e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        uint8_t led = entry.data.u8[i];
583e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
584e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        switch(led) {
585e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
586e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
587e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
588e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                    metadata.update(ANDROID_LED_TRANSMIT,
589e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                                    &transmitDefault, 1);
590e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                }
591e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                break;
592e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            }
593e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
594e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
595e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
596e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    // We can do anything!
597e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (pid == selfPid) {
598e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        return true;
599e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
600e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
601e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    /**
602e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * Permission check special fields in the request
603e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
604e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin     */
605e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    entry = metadata.find(ANDROID_LED_TRANSMIT);
606e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
607e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        String16 permissionString =
608e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
609e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        if (!checkCallingPermission(permissionString)) {
610e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            const int uid = IPCThreadState::self()->getCallingUid();
611e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            ALOGE("Permission Denial: "
612e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
613e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin            return false;
614e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin        }
615e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    }
616e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
617e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin    return true;
618e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin}
619e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin
620f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkinstatus_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
621f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    ALOGV("%s: begin", __FUNCTION__);
622f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
623f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    if (transform == NULL) {
624f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        ALOGW("%s: null transform", __FUNCTION__);
625f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        return BAD_VALUE;
626f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    }
627f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
628f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    *transform = 0;
629f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
630f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    const CameraMetadata& staticInfo = mDevice->info();
631f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
632f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    if (entry.count == 0) {
633f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        ALOGE("%s: Camera %d: Can't find android.sensor.orientation in "
634f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin                "static metadata!", __FUNCTION__, mCameraId);
635f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        return INVALID_OPERATION;
636f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    }
637f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
638f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    int32_t& flags = *transform;
639f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
640f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    int orientation = entry.data.i32[0];
641f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    switch (orientation) {
642f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        case 0:
643f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            flags = 0;
644f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            break;
645f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        case 90:
646f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
647f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            break;
648f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        case 180:
649f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
650f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            break;
651f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        case 270:
652f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
653f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            break;
654f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin        default:
655f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
656f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin                  __FUNCTION__, orientation);
657f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin            return INVALID_OPERATION;
658f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    }
659f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
660f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    /**
661f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * This magic flag makes surfaceflinger un-rotate the buffers
662f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * to counter the extra global device UI rotation whenever the user
663f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * physically rotates the device.
664f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     *
665f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * By doing this, the camera buffer always ends up aligned
666f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * with the physical camera for a "see through" effect.
667f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     *
668f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * In essence, the buffer only gets rotated during preview use-cases.
669f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * The user is still responsible to re-create streams of the proper
670f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * aspect ratio, or the preview will end up looking non-uniformly
671f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     * stretched.
672f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin     */
673f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
674f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
675f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
676f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
677f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin    return OK;
678f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin}
679f8b2a6f7dea06234c7966798d9363d2d236488a6Igor Murashkin
680e7ee7637747371635a85fedd24d2190bb1f38651Igor Murashkin} // namespace android
681