Camera2Client.cpp revision 36cdfb185877a7f573621d19ed2b2e1cac13d62e
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Client"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Trace.h>
23
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
27#include <media/hardware/MetadataBufferType.h>
28
29#include <math.h>
30
31#include "Camera2Client.h"
32
33namespace android {
34
35#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
36#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
37
38static int getCallingPid() {
39    return IPCThreadState::self()->getCallingPid();
40}
41
42static int getCallingUid() {
43    return IPCThreadState::self()->getCallingUid();
44}
45
46// Interface used by CameraService
47
48Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
49        const sp<ICameraClient>& cameraClient,
50        int cameraId,
51        int cameraFacing,
52        int clientPid):
53        Client(cameraService, cameraClient,
54                cameraId, cameraFacing, clientPid),
55        mState(DISCONNECTED),
56        mPreviewStreamId(NO_STREAM),
57        mPreviewRequest(NULL),
58        mCaptureStreamId(NO_STREAM),
59        mCaptureRequest(NULL),
60        mRecordingStreamId(NO_STREAM),
61        mRecordingRequest(NULL),
62        mRecordingHeapCount(kDefaultRecordingHeapCount)
63{
64    ATRACE_CALL();
65
66    mDevice = new Camera2Device(cameraId);
67}
68
69status_t Camera2Client::checkPid(const char* checkLocation) const {
70    int callingPid = getCallingPid();
71    if (callingPid == mClientPid) return NO_ERROR;
72
73    ALOGE("%s: attempt to use a locked camera from a different process"
74            " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
75    return PERMISSION_DENIED;
76}
77
78status_t Camera2Client::initialize(camera_module_t *module)
79{
80    ATRACE_CALL();
81    ALOGV("%s: E", __FUNCTION__);
82    status_t res;
83
84    res = mDevice->initialize(module);
85    if (res != OK) {
86        ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
87                __FUNCTION__, mCameraId, strerror(-res), res);
88        return NO_INIT;
89    }
90
91    res = buildDefaultParameters();
92    if (res != OK) {
93        ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
94                __FUNCTION__, mCameraId, strerror(-res), res);
95        return NO_INIT;
96    }
97
98    if (gLogLevel >= 1) {
99        LockedParameters::Key k(mParameters);
100        ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
101              mCameraId);
102        ALOGD("%s", k.mParameters.paramsFlattened.string());
103    }
104
105    mState = STOPPED;
106
107    return OK;
108}
109
110Camera2Client::~Camera2Client() {
111    ATRACE_CALL();
112    ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
113
114    mDestructionStarted = true;
115
116    // Rewrite mClientPid to allow shutdown by CameraService
117    mClientPid = getCallingPid();
118    disconnect();
119
120}
121
122status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
123    String8 result;
124    result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
125            mCameraId,
126            getCameraClient()->asBinder().get(),
127            mClientPid);
128    result.append("  State: ");
129#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
130
131    const Parameters& p = mParameters.unsafeUnlock();
132
133    result.append(getStateName(mState));
134
135    result.append("\n  Current parameters:\n");
136    result.appendFormat("    Preview size: %d x %d\n",
137            p.previewWidth, p.previewHeight);
138    result.appendFormat("    Preview FPS range: %d - %d\n",
139            p.previewFpsRange[0], p.previewFpsRange[1]);
140    result.appendFormat("    Preview HAL pixel format: 0x%x\n",
141            p.previewFormat);
142    result.appendFormat("    Preview transform: %x\n",
143            p.previewTransform);
144    result.appendFormat("    Picture size: %d x %d\n",
145            p.pictureWidth, p.pictureHeight);
146    result.appendFormat("    Jpeg thumbnail size: %d x %d\n",
147            p.jpegThumbSize[0], p.jpegThumbSize[1]);
148    result.appendFormat("    Jpeg quality: %d, thumbnail quality: %d\n",
149            p.jpegQuality, p.jpegThumbQuality);
150    result.appendFormat("    Jpeg rotation: %d\n", p.jpegRotation);
151    result.appendFormat("    GPS tags %s\n",
152            p.gpsEnabled ? "enabled" : "disabled");
153    if (p.gpsEnabled) {
154        result.appendFormat("    GPS lat x long x alt: %f x %f x %f\n",
155                p.gpsCoordinates[0], p.gpsCoordinates[1],
156                p.gpsCoordinates[2]);
157        result.appendFormat("    GPS timestamp: %lld\n",
158                p.gpsTimestamp);
159        result.appendFormat("    GPS processing method: %s\n",
160                p.gpsProcessingMethod.string());
161    }
162
163    result.append("    White balance mode: ");
164    switch (p.wbMode) {
165        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
166        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
167        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
168        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
169        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
170        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
171        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
172        CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
173        default: result.append("UNKNOWN\n");
174    }
175
176    result.append("    Effect mode: ");
177    switch (p.effectMode) {
178        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
179        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
180        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
181        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
182        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
183        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
184        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
185        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
186        CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
187        default: result.append("UNKNOWN\n");
188    }
189
190    result.append("    Antibanding mode: ");
191    switch (p.antibandingMode) {
192        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
193        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
194        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
195        CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
196        default: result.append("UNKNOWN\n");
197    }
198
199    result.append("    Scene mode: ");
200    switch (p.sceneMode) {
201        case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
202            result.append("AUTO\n"); break;
203        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
204        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
205        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
206        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
207        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
208        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
209        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
210        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
211        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
212        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
213        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
214        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
215        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
216        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
217        CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
218        default: result.append("UNKNOWN\n");
219    }
220
221    result.append("    Flash mode: ");
222    switch (p.flashMode) {
223        CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
224        CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
225        CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
226        CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
227        CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
228        CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
229        default: result.append("UNKNOWN\n");
230    }
231
232    result.append("    Focus mode: ");
233    switch (p.focusMode) {
234        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
235        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
236        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
237        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
238        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
239        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
240        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
241        CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
242        default: result.append("UNKNOWN\n");
243    }
244
245    result.append("    Focusing areas:\n");
246    for (size_t i = 0; i < p.focusingAreas.size(); i++) {
247        result.appendFormat("      [ (%d, %d, %d, %d), weight %d ]\n",
248                p.focusingAreas[i].left,
249                p.focusingAreas[i].top,
250                p.focusingAreas[i].right,
251                p.focusingAreas[i].bottom,
252                p.focusingAreas[i].weight);
253    }
254
255    result.appendFormat("    Exposure compensation index: %d\n",
256            p.exposureCompensation);
257
258    result.appendFormat("    AE lock %s, AWB lock %s\n",
259            p.autoExposureLock ? "enabled" : "disabled",
260            p.autoWhiteBalanceLock ? "enabled" : "disabled" );
261
262    result.appendFormat("    Metering areas:\n");
263    for (size_t i = 0; i < p.meteringAreas.size(); i++) {
264        result.appendFormat("      [ (%d, %d, %d, %d), weight %d ]\n",
265                p.meteringAreas[i].left,
266                p.meteringAreas[i].top,
267                p.meteringAreas[i].right,
268                p.meteringAreas[i].bottom,
269                p.meteringAreas[i].weight);
270    }
271
272    result.appendFormat("    Zoom index: %d\n", p.zoom);
273    result.appendFormat("    Video size: %d x %d\n", p.videoWidth,
274            p.videoHeight);
275
276    result.appendFormat("    Recording hint is %s\n",
277            p.recordingHint ? "set" : "not set");
278
279    result.appendFormat("    Video stabilization is %s\n",
280            p.videoStabilization ? "enabled" : "disabled");
281
282    result.append("  Current streams:\n");
283    result.appendFormat("    Preview stream ID: %d\n", mPreviewStreamId);
284    result.appendFormat("    Capture stream ID: %d\n", mCaptureStreamId);
285    result.appendFormat("    Recording stream ID: %d\n", mRecordingStreamId);
286
287    result.append("  Current requests:\n");
288    if (mPreviewRequest != NULL) {
289        result.append("    Preview request:\n");
290        write(fd, result.string(), result.size());
291        dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
292    } else {
293        result.append("    Preview request: undefined\n");
294        write(fd, result.string(), result.size());
295    }
296
297    if (mCaptureRequest != NULL) {
298        result = "    Capture request:\n";
299        write(fd, result.string(), result.size());
300        dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
301    } else {
302        result = "    Capture request: undefined\n";
303        write(fd, result.string(), result.size());
304    }
305
306    if (mRecordingRequest != NULL) {
307        result = "    Recording request:\n";
308        write(fd, result.string(), result.size());
309        dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
310    } else {
311        result = "    Recording request: undefined\n";
312        write(fd, result.string(), result.size());
313    }
314
315    result = "  Device dump:\n";
316    write(fd, result.string(), result.size());
317
318    status_t res = mDevice->dump(fd, args);
319    if (res != OK) {
320        result = String8::format("   Error dumping device: %s (%d)",
321                strerror(-res), res);
322        write(fd, result.string(), result.size());
323    }
324
325#undef CASE_APPEND_ENUM
326    return NO_ERROR;
327}
328
329const char* Camera2Client::getStateName(State state) {
330#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
331    switch(state) {
332        CASE_ENUM_TO_CHAR(DISCONNECTED)
333        CASE_ENUM_TO_CHAR(STOPPED)
334        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
335        CASE_ENUM_TO_CHAR(PREVIEW)
336        CASE_ENUM_TO_CHAR(RECORD)
337        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
338        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
339        default:
340            return "Unknown state!";
341            break;
342    }
343#undef CASE_ENUM_TO_CHAR
344}
345
346// ICamera interface
347
348void Camera2Client::disconnect() {
349    ATRACE_CALL();
350    ALOGV("%s: E", __FUNCTION__);
351    Mutex::Autolock icl(mICameraLock);
352    status_t res;
353    if ( (res = checkPid(__FUNCTION__) ) != OK) return;
354
355    if (mDevice == 0) return;
356
357    stopPreviewL();
358
359    mDevice->waitUntilDrained();
360
361    if (mPreviewStreamId != NO_STREAM) {
362        mDevice->deleteStream(mPreviewStreamId);
363        mPreviewStreamId = NO_STREAM;
364    }
365
366    if (mCaptureStreamId != NO_STREAM) {
367        mDevice->deleteStream(mCaptureStreamId);
368        mCaptureStreamId = NO_STREAM;
369    }
370
371    if (mRecordingStreamId != NO_STREAM) {
372        mDevice->deleteStream(mRecordingStreamId);
373        mRecordingStreamId = NO_STREAM;
374    }
375
376    mDevice.clear();
377    mState = DISCONNECTED;
378
379    CameraService::Client::disconnect();
380}
381
382status_t Camera2Client::connect(const sp<ICameraClient>& client) {
383    ATRACE_CALL();
384    ALOGV("%s: E", __FUNCTION__);
385    Mutex::Autolock icl(mICameraLock);
386
387    if (mClientPid != 0 && getCallingPid() != mClientPid) {
388        ALOGE("%s: Camera %d: Connection attempt from pid %d; "
389                "current locked to pid %d", __FUNCTION__,
390                mCameraId, getCallingPid(), mClientPid);
391        return BAD_VALUE;
392    }
393
394    mClientPid = getCallingPid();
395    mCameraClient = client;
396
397    return OK;
398}
399
400status_t Camera2Client::lock() {
401    ATRACE_CALL();
402    ALOGV("%s: E", __FUNCTION__);
403    Mutex::Autolock icl(mICameraLock);
404    ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
405            __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
406
407    if (mClientPid == 0) {
408        mClientPid = getCallingPid();
409        return OK;
410    }
411
412    if (mClientPid != getCallingPid()) {
413        ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
414                __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
415        return EBUSY;
416    }
417
418    return OK;
419}
420
421status_t Camera2Client::unlock() {
422    ATRACE_CALL();
423    ALOGV("%s: E", __FUNCTION__);
424    Mutex::Autolock icl(mICameraLock);
425    ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
426            __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
427
428    // TODO: Check for uninterruptable conditions
429
430    if (mClientPid == getCallingPid()) {
431        mClientPid = 0;
432        mCameraClient.clear();
433        return OK;
434    }
435
436    ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
437            __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
438    return EBUSY;
439}
440
441status_t Camera2Client::setPreviewDisplay(
442        const sp<Surface>& surface) {
443    ATRACE_CALL();
444    ALOGV("%s: E", __FUNCTION__);
445    Mutex::Autolock icl(mICameraLock);
446    status_t res;
447    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
448
449    sp<IBinder> binder;
450    sp<ANativeWindow> window;
451    if (surface != 0) {
452        binder = surface->asBinder();
453        window = surface;
454    }
455
456    return setPreviewWindowL(binder,window);
457}
458
459status_t Camera2Client::setPreviewTexture(
460        const sp<ISurfaceTexture>& surfaceTexture) {
461    ATRACE_CALL();
462    ALOGV("%s: E", __FUNCTION__);
463    Mutex::Autolock icl(mICameraLock);
464    status_t res;
465    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
466
467    sp<IBinder> binder;
468    sp<ANativeWindow> window;
469    if (surfaceTexture != 0) {
470        binder = surfaceTexture->asBinder();
471        window = new SurfaceTextureClient(surfaceTexture);
472    }
473    return setPreviewWindowL(binder, window);
474}
475
476status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
477        sp<ANativeWindow> window) {
478    ATRACE_CALL();
479    status_t res;
480
481    if (binder == mPreviewSurface) {
482        ALOGV("%s: Camera %d: New window is same as old window",
483                __FUNCTION__, mCameraId);
484        return NO_ERROR;
485    }
486
487    switch (mState) {
488        case DISCONNECTED:
489        case RECORD:
490        case STILL_CAPTURE:
491        case VIDEO_SNAPSHOT:
492            ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
493                    __FUNCTION__, mCameraId, getStateName(mState));
494            return INVALID_OPERATION;
495        case STOPPED:
496        case WAITING_FOR_PREVIEW_WINDOW:
497            // OK
498            break;
499        case PREVIEW:
500            // Already running preview - need to stop and create a new stream
501            // TODO: Optimize this so that we don't wait for old stream to drain
502            // before spinning up new stream
503            mDevice->setStreamingRequest(NULL);
504            mState = WAITING_FOR_PREVIEW_WINDOW;
505            break;
506    }
507
508    if (mPreviewStreamId != NO_STREAM) {
509        res = mDevice->waitUntilDrained();
510        if (res != OK) {
511            ALOGE("%s: Error waiting for preview to drain: %s (%d)",
512                    __FUNCTION__, strerror(-res), res);
513            return res;
514        }
515        res = mDevice->deleteStream(mPreviewStreamId);
516        if (res != OK) {
517            ALOGE("%s: Unable to delete old preview stream: %s (%d)",
518                    __FUNCTION__, strerror(-res), res);
519            return res;
520        }
521        mPreviewStreamId = NO_STREAM;
522    }
523
524    mPreviewSurface = binder;
525    mPreviewWindow = window;
526
527    if (mState == WAITING_FOR_PREVIEW_WINDOW) {
528        return startPreviewL();
529    }
530
531    return OK;
532}
533
534void Camera2Client::setPreviewCallbackFlag(int flag) {
535    ATRACE_CALL();
536    Mutex::Autolock icl(mICameraLock);
537    status_t res;
538    if ( (res = checkPid(__FUNCTION__) ) != OK) return;
539}
540
541status_t Camera2Client::startPreview() {
542    ATRACE_CALL();
543    ALOGV("%s: E", __FUNCTION__);
544    Mutex::Autolock icl(mICameraLock);
545    status_t res;
546    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
547    return startPreviewL();
548}
549
550status_t Camera2Client::startPreviewL() {
551    ATRACE_CALL();
552    status_t res;
553    if (mState >= PREVIEW) {
554        ALOGE("%s: Can't start preview in state %s",
555                __FUNCTION__, getStateName(mState));
556        return INVALID_OPERATION;
557    }
558
559    if (mPreviewWindow == 0) {
560        mState = WAITING_FOR_PREVIEW_WINDOW;
561        return OK;
562    }
563    mState = STOPPED;
564
565    LockedParameters::Key k(mParameters);
566
567    res = updatePreviewStream(k.mParameters);
568    if (res != OK) {
569        ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
570                __FUNCTION__, mCameraId, strerror(-res), res);
571        return res;
572    }
573
574    if (mPreviewRequest == NULL) {
575        res = updatePreviewRequest(k.mParameters);
576        if (res != OK) {
577            ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
578                    __FUNCTION__, mCameraId, strerror(-res), res);
579            return res;
580        }
581    }
582
583    res = updateEntry(mPreviewRequest,
584            ANDROID_REQUEST_OUTPUT_STREAMS,
585            &mPreviewStreamId, 1);
586    if (res != OK) {
587        ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
588                __FUNCTION__, mCameraId, strerror(-res), res);
589        return res;
590    }
591    res = sort_camera_metadata(mPreviewRequest);
592    if (res != OK) {
593        ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
594                __FUNCTION__, mCameraId, strerror(-res), res);
595        return res;
596    }
597
598    res = mDevice->setStreamingRequest(mPreviewRequest);
599    if (res != OK) {
600        ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
601                "%s (%d)",
602                __FUNCTION__, mCameraId, strerror(-res), res);
603        return res;
604    }
605    mState = PREVIEW;
606
607    return OK;
608}
609
610void Camera2Client::stopPreview() {
611    ATRACE_CALL();
612    ALOGV("%s: E", __FUNCTION__);
613    Mutex::Autolock icl(mICameraLock);
614    status_t res;
615    if ( (res = checkPid(__FUNCTION__) ) != OK) return;
616    stopPreviewL();
617}
618
619void Camera2Client::stopPreviewL() {
620    ATRACE_CALL();
621    switch (mState) {
622        case DISCONNECTED:
623            ALOGE("%s: Camera %d: Call before initialized",
624                    __FUNCTION__, mCameraId);
625            break;
626        case STOPPED:
627            break;
628        case STILL_CAPTURE:
629            ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
630                    __FUNCTION__, mCameraId);
631            break;
632        case RECORD:
633            // TODO: Handle record stop here
634        case PREVIEW:
635            mDevice->setStreamingRequest(NULL);
636            mDevice->waitUntilDrained();
637        case WAITING_FOR_PREVIEW_WINDOW:
638            mState = STOPPED;
639            break;
640        default:
641            ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
642                    mState);
643    }
644}
645
646bool Camera2Client::previewEnabled() {
647    ATRACE_CALL();
648    Mutex::Autolock icl(mICameraLock);
649    status_t res;
650    if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
651
652    return mState == PREVIEW;
653}
654
655status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
656    ATRACE_CALL();
657    Mutex::Autolock icl(mICameraLock);
658    status_t res;
659    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
660
661    switch (mState) {
662        case RECORD:
663        case VIDEO_SNAPSHOT:
664            ALOGE("%s: Camera %d: Can't be called in state %s",
665                    __FUNCTION__, mCameraId, getStateName(mState));
666            return INVALID_OPERATION;
667        default:
668            // OK
669            break;
670    }
671    LockedParameters::Key k(mParameters);
672
673    k.mParameters.storeMetadataInBuffers = enabled;
674
675    return OK;
676}
677
678status_t Camera2Client::startRecording() {
679    ATRACE_CALL();
680    ALOGV("%s: E", __FUNCTION__);
681    Mutex::Autolock icl(mICameraLock);
682    status_t res;
683    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
684
685    switch (mState) {
686        case STOPPED:
687            res = startPreviewL();
688            if (res != OK) return res;
689            break;
690        case PREVIEW:
691            // Ready to go
692            break;
693        case RECORD:
694        case VIDEO_SNAPSHOT:
695            // OK to call this when recording is already on
696            return OK;
697            break;
698        default:
699            ALOGE("%s: Camera %d: Can't start recording in state %s",
700                    __FUNCTION__, mCameraId, getStateName(mState));
701            return INVALID_OPERATION;
702    };
703
704    LockedParameters::Key k(mParameters);
705
706    if (!k.mParameters.storeMetadataInBuffers) {
707        ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
708                "non-metadata recording mode requested!", __FUNCTION__,
709                mCameraId);
710        return INVALID_OPERATION;
711    }
712
713    res = updateRecordingStream(k.mParameters);
714    if (res != OK) {
715        ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
716                __FUNCTION__, mCameraId, strerror(-res), res);
717        return res;
718    }
719
720    if (mRecordingRequest == NULL) {
721        res = updateRecordingRequest(k.mParameters);
722        if (res != OK) {
723            ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
724                    __FUNCTION__, mCameraId, strerror(-res), res);
725            return res;
726        }
727    }
728
729    uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
730    res = updateEntry(mRecordingRequest,
731            ANDROID_REQUEST_OUTPUT_STREAMS,
732            outputStreams, 2);
733    if (res != OK) {
734        ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
735                __FUNCTION__, mCameraId, strerror(-res), res);
736        return res;
737    }
738    res = sort_camera_metadata(mRecordingRequest);
739    if (res != OK) {
740        ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
741                __FUNCTION__, mCameraId, strerror(-res), res);
742        return res;
743    }
744
745    res = mDevice->setStreamingRequest(mRecordingRequest);
746    if (res != OK) {
747        ALOGE("%s: Camera %d: Unable to set recording request to start "
748                "recording: %s (%d)", __FUNCTION__, mCameraId,
749                strerror(-res), res);
750        return res;
751    }
752    mState = RECORD;
753
754    return OK;
755}
756
757void Camera2Client::stopRecording() {
758    ATRACE_CALL();
759    ALOGV("%s: E", __FUNCTION__);
760    Mutex::Autolock icl(mICameraLock);
761    status_t res;
762    if ( (res = checkPid(__FUNCTION__) ) != OK) return;
763
764    switch (mState) {
765        case RECORD:
766            // OK to stop
767            break;
768        case STOPPED:
769        case PREVIEW:
770        case STILL_CAPTURE:
771        case VIDEO_SNAPSHOT:
772        default:
773            ALOGE("%s: Camera %d: Can't stop recording in state %s",
774                    __FUNCTION__, mCameraId, getStateName(mState));
775            return;
776    };
777
778    // Back to preview. Since record can only be reached through preview,
779    // all preview stream setup should be up to date.
780    res = mDevice->setStreamingRequest(mPreviewRequest);
781    if (res != OK) {
782        ALOGE("%s: Camera %d: Unable to switch back to preview request: "
783                "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
784        return;
785    }
786
787    // TODO: Should recording heap be freed? Can't do it yet since requests
788    // could still be in flight.
789
790    mState = PREVIEW;
791}
792
793bool Camera2Client::recordingEnabled() {
794    ATRACE_CALL();
795    Mutex::Autolock icl(mICameraLock);
796    if ( checkPid(__FUNCTION__) != OK) return false;
797
798    return (mState == RECORD || mState == VIDEO_SNAPSHOT);
799}
800
801void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
802    ATRACE_CALL();
803    Mutex::Autolock icl(mICameraLock);
804    status_t res;
805    if ( checkPid(__FUNCTION__) != OK) return;
806    // Make sure this is for the current heap
807    ssize_t offset;
808    size_t size;
809    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
810    if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
811        ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
812                "(got %x, expected %x)", __FUNCTION__, mCameraId,
813                heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
814        return;
815    }
816    uint8_t *data = (uint8_t*)heap->getBase() + offset;
817    uint32_t type = *(uint32_t*)data;
818    if (type != kMetadataBufferTypeGrallocSource) {
819        ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
820                __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
821        return;
822    }
823    buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
824    ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
825            imgBuffer);
826    res = mRecordingConsumer->freeBuffer(imgBuffer);
827    if (res != OK) {
828        ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
829                "%s (%d)",
830                __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
831        return;
832    }
833
834    mRecordingHeapFree++;
835}
836
837status_t Camera2Client::autoFocus() {
838    ATRACE_CALL();
839    Mutex::Autolock icl(mICameraLock);
840    status_t res;
841    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
842
843    return OK;
844}
845
846status_t Camera2Client::cancelAutoFocus() {
847    ATRACE_CALL();
848    Mutex::Autolock icl(mICameraLock);
849    status_t res;
850    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
851
852    return OK;
853}
854
855status_t Camera2Client::takePicture(int msgType) {
856    ATRACE_CALL();
857    Mutex::Autolock icl(mICameraLock);
858    status_t res;
859    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
860
861    switch (mState) {
862        case DISCONNECTED:
863        case STOPPED:
864        case WAITING_FOR_PREVIEW_WINDOW:
865            ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
866                    __FUNCTION__, mCameraId);
867            return INVALID_OPERATION;
868        case PREVIEW:
869        case RECORD:
870            // Good to go for takePicture
871            break;
872        case STILL_CAPTURE:
873        case VIDEO_SNAPSHOT:
874            ALOGE("%s: Camera %d: Already taking a picture",
875                    __FUNCTION__, mCameraId);
876            return INVALID_OPERATION;
877    }
878
879    LockedParameters::Key k(mParameters);
880
881    res = updateCaptureStream(k.mParameters);
882    if (res != OK) {
883        ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
884                __FUNCTION__, mCameraId, strerror(-res), res);
885        return res;
886    }
887
888    if (mCaptureRequest == NULL) {
889        res = updateCaptureRequest(k.mParameters);
890        if (res != OK) {
891            ALOGE("%s: Camera %d: Can't create still image capture request: "
892                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
893            return res;
894        }
895    }
896
897    camera_metadata_entry_t outputStreams;
898    if (mState == PREVIEW) {
899        uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
900        res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
901                &streamIds, 2);
902    } else if (mState == RECORD) {
903        uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
904                                 mCaptureStreamId };
905        res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
906                &streamIds, 3);
907    }
908
909    if (res != OK) {
910        ALOGE("%s: Camera %d: Unable to set up still image capture request: "
911                "%s (%d)",
912                __FUNCTION__, mCameraId, strerror(-res), res);
913        return res;
914    }
915    res = sort_camera_metadata(mCaptureRequest);
916    if (res != OK) {
917        ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
918                __FUNCTION__, mCameraId, strerror(-res), res);
919        return res;
920    }
921
922    camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
923    if (captureCopy == NULL) {
924        ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
925                __FUNCTION__, mCameraId);
926        return NO_MEMORY;
927    }
928
929    if (mState == PREVIEW) {
930        res = mDevice->setStreamingRequest(NULL);
931        if (res != OK) {
932            ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
933                    "%s (%d)",
934                    __FUNCTION__, mCameraId, strerror(-res), res);
935            return res;
936        }
937    }
938    // TODO: Capture should be atomic with setStreamingRequest here
939    res = mDevice->capture(captureCopy);
940    if (res != OK) {
941        ALOGE("%s: Camera %d: Unable to submit still image capture request: "
942                "%s (%d)",
943                __FUNCTION__, mCameraId, strerror(-res), res);
944        return res;
945    }
946
947    switch (mState) {
948        case PREVIEW:
949            mState = STILL_CAPTURE;
950            break;
951        case RECORD:
952            mState = VIDEO_SNAPSHOT;
953            break;
954        default:
955            ALOGE("%s: Camera %d: Unknown state for still capture!",
956                    __FUNCTION__, mCameraId);
957            return INVALID_OPERATION;
958    }
959
960    return OK;
961}
962
963status_t Camera2Client::setParameters(const String8& params) {
964    ATRACE_CALL();
965    ALOGV("%s: E", __FUNCTION__);
966    Mutex::Autolock icl(mICameraLock);
967    status_t res;
968    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
969
970    LockedParameters::Key k(mParameters);
971
972    CameraParameters newParams(params);
973
974    // TODO: Currently ignoring any changes to supposedly read-only
975    // parameters such as supported preview sizes, etc. Should probably
976    // produce an error if they're changed.
977
978    /** Extract and verify new parameters */
979
980    size_t i;
981
982    // PREVIEW_SIZE
983    int previewWidth, previewHeight;
984    newParams.getPreviewSize(&previewWidth, &previewHeight);
985
986    if (previewWidth != k.mParameters.previewWidth ||
987            previewHeight != k.mParameters.previewHeight) {
988        if (mState >= PREVIEW) {
989            ALOGE("%s: Preview size cannot be updated when preview "
990                    "is active! (Currently %d x %d, requested %d x %d",
991                    __FUNCTION__,
992                    k.mParameters.previewWidth, k.mParameters.previewHeight,
993                    previewWidth, previewHeight);
994            return BAD_VALUE;
995        }
996        camera_metadata_entry_t availablePreviewSizes =
997            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
998        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
999            if (availablePreviewSizes.data.i32[i] == previewWidth &&
1000                    availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1001        }
1002        if (i == availablePreviewSizes.count) {
1003            ALOGE("%s: Requested preview size %d x %d is not supported",
1004                    __FUNCTION__, previewWidth, previewHeight);
1005            return BAD_VALUE;
1006        }
1007    }
1008
1009    // PREVIEW_FPS_RANGE
1010    int previewFpsRange[2];
1011    int previewFps = 0;
1012    bool fpsRangeChanged = false;
1013    newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
1014    if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1015            previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
1016        fpsRangeChanged = true;
1017        camera_metadata_entry_t availablePreviewFpsRanges =
1018            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1019        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1020            if ((availablePreviewFpsRanges.data.i32[i] ==
1021                    previewFpsRange[0]) &&
1022                (availablePreviewFpsRanges.data.i32[i+1] ==
1023                    previewFpsRange[1]) ) {
1024                break;
1025            }
1026        }
1027        if (i == availablePreviewFpsRanges.count) {
1028            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
1029                __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
1030            return BAD_VALUE;
1031        }
1032        previewFps = previewFpsRange[0];
1033    }
1034
1035    // PREVIEW_FORMAT
1036    int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
1037    if (previewFormat != k.mParameters.previewFormat) {
1038        if (mState >= PREVIEW) {
1039            ALOGE("%s: Preview format cannot be updated when preview "
1040                    "is active!", __FUNCTION__);
1041            return BAD_VALUE;
1042        }
1043        camera_metadata_entry_t availableFormats =
1044            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1045        for (i = 0; i < availableFormats.count; i++) {
1046            if (availableFormats.data.i32[i] == previewFormat) break;
1047        }
1048        if (i == availableFormats.count) {
1049            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1050                    __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1051            return BAD_VALUE;
1052        }
1053    }
1054
1055    // PREVIEW_FRAME_RATE
1056    // Deprecated, only use if the preview fps range is unchanged this time.
1057    // The single-value FPS is the same as the minimum of the range.
1058    if (!fpsRangeChanged) {
1059        previewFps = newParams.getPreviewFrameRate();
1060        if (previewFps != k.mParameters.previewFps) {
1061            camera_metadata_entry_t availableFrameRates =
1062                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1063            for (i = 0; i < availableFrameRates.count; i+=2) {
1064                if (availableFrameRates.data.i32[i] == previewFps) break;
1065            }
1066            if (i == availableFrameRates.count) {
1067                ALOGE("%s: Requested preview frame rate %d is not supported",
1068                        __FUNCTION__, previewFps);
1069                return BAD_VALUE;
1070            }
1071            previewFpsRange[0] = availableFrameRates.data.i32[i];
1072            previewFpsRange[1] = availableFrameRates.data.i32[i+1];
1073        }
1074    }
1075
1076    // PICTURE_SIZE
1077    int pictureWidth, pictureHeight;
1078    newParams.getPictureSize(&pictureWidth, &pictureHeight);
1079    if (pictureWidth == k.mParameters.pictureWidth ||
1080            pictureHeight == k.mParameters.pictureHeight) {
1081        camera_metadata_entry_t availablePictureSizes =
1082            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1083        for (i = 0; i < availablePictureSizes.count; i+=2) {
1084            if (availablePictureSizes.data.i32[i] == pictureWidth &&
1085                    availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1086        }
1087        if (i == availablePictureSizes.count) {
1088            ALOGE("%s: Requested picture size %d x %d is not supported",
1089                    __FUNCTION__, pictureWidth, pictureHeight);
1090            return BAD_VALUE;
1091        }
1092    }
1093
1094    // JPEG_THUMBNAIL_WIDTH/HEIGHT
1095    int jpegThumbSize[2];
1096    jpegThumbSize[0] =
1097            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1098    jpegThumbSize[1] =
1099            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
1100    if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1101            jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
1102        camera_metadata_entry_t availableJpegThumbSizes =
1103            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1104        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
1105            if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1106                    availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
1107                break;
1108            }
1109        }
1110        if (i == availableJpegThumbSizes.count) {
1111            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1112                    __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
1113            return BAD_VALUE;
1114        }
1115    }
1116
1117    // JPEG_THUMBNAIL_QUALITY
1118    int jpegThumbQuality =
1119            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1120    if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1121        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1122                __FUNCTION__, jpegThumbQuality);
1123        return BAD_VALUE;
1124    }
1125
1126    // JPEG_QUALITY
1127    int jpegQuality =
1128            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1129    if (jpegQuality < 0 || jpegQuality > 100) {
1130        ALOGE("%s: Requested JPEG quality %d is not supported",
1131                __FUNCTION__, jpegQuality);
1132        return BAD_VALUE;
1133    }
1134
1135    // ROTATION
1136    int jpegRotation =
1137            newParams.getInt(CameraParameters::KEY_ROTATION);
1138    if (jpegRotation != 0 &&
1139            jpegRotation != 90 &&
1140            jpegRotation != 180 &&
1141            jpegRotation != 270) {
1142        ALOGE("%s: Requested picture rotation angle %d is not supported",
1143                __FUNCTION__, jpegRotation);
1144        return BAD_VALUE;
1145    }
1146
1147    // GPS
1148    bool gpsEnabled = false;
1149    double gpsCoordinates[3] = {0,0,0};
1150    int64_t gpsTimestamp = 0;
1151    String8 gpsProcessingMethod;
1152    const char *gpsLatStr =
1153            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1154    if (gpsLatStr != NULL) {
1155        const char *gpsLongStr =
1156                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1157        const char *gpsAltitudeStr =
1158                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1159        const char *gpsTimeStr =
1160                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1161        const char *gpsProcMethodStr =
1162                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1163        if (gpsLongStr == NULL ||
1164                gpsAltitudeStr == NULL ||
1165                gpsTimeStr == NULL ||
1166                gpsProcMethodStr == NULL) {
1167            ALOGE("%s: Incomplete set of GPS parameters provided",
1168                    __FUNCTION__);
1169            return BAD_VALUE;
1170        }
1171        char *endPtr;
1172        errno = 0;
1173        gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1174        if (errno || endPtr == gpsLatStr) {
1175            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1176            return BAD_VALUE;
1177        }
1178        errno = 0;
1179        gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1180        if (errno || endPtr == gpsLongStr) {
1181            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1182            return BAD_VALUE;
1183        }
1184        errno = 0;
1185        gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1186        if (errno || endPtr == gpsAltitudeStr) {
1187            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1188                    gpsAltitudeStr);
1189            return BAD_VALUE;
1190        }
1191        errno = 0;
1192        gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1193        if (errno || endPtr == gpsTimeStr) {
1194            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1195            return BAD_VALUE;
1196        }
1197        gpsProcessingMethod = gpsProcMethodStr;
1198
1199        gpsEnabled = true;
1200    }
1201
1202    // WHITE_BALANCE
1203    int wbMode = wbModeStringToEnum(
1204        newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1205    if (wbMode != k.mParameters.wbMode) {
1206        camera_metadata_entry_t availableWbModes =
1207            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1208        for (i = 0; i < availableWbModes.count; i++) {
1209            if (wbMode == availableWbModes.data.u8[i]) break;
1210        }
1211        if (i == availableWbModes.count) {
1212            ALOGE("%s: Requested white balance mode %s is not supported",
1213                    __FUNCTION__,
1214                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1215            return BAD_VALUE;
1216        }
1217    }
1218
1219    // EFFECT
1220    int effectMode = effectModeStringToEnum(
1221        newParams.get(CameraParameters::KEY_EFFECT) );
1222    if (effectMode != k.mParameters.effectMode) {
1223        camera_metadata_entry_t availableEffectModes =
1224            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1225        for (i = 0; i < availableEffectModes.count; i++) {
1226            if (effectMode == availableEffectModes.data.u8[i]) break;
1227        }
1228        if (i == availableEffectModes.count) {
1229            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1230                    __FUNCTION__,
1231                    newParams.get(CameraParameters::KEY_EFFECT) );
1232            return BAD_VALUE;
1233        }
1234    }
1235
1236    // ANTIBANDING
1237    int antibandingMode = abModeStringToEnum(
1238        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1239    if (antibandingMode != k.mParameters.antibandingMode) {
1240        camera_metadata_entry_t availableAbModes =
1241            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1242        for (i = 0; i < availableAbModes.count; i++) {
1243            if (antibandingMode == availableAbModes.data.u8[i]) break;
1244        }
1245        if (i == availableAbModes.count) {
1246            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1247                    __FUNCTION__,
1248                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1249            return BAD_VALUE;
1250        }
1251    }
1252
1253    // SCENE_MODE
1254    int sceneMode = sceneModeStringToEnum(
1255        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1256    if (sceneMode != k.mParameters.sceneMode) {
1257        camera_metadata_entry_t availableSceneModes =
1258            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1259        for (i = 0; i < availableSceneModes.count; i++) {
1260            if (sceneMode == availableSceneModes.data.u8[i]) break;
1261        }
1262        if (i == availableSceneModes.count) {
1263            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1264                    __FUNCTION__,
1265                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1266            return BAD_VALUE;
1267        }
1268    }
1269
1270    // FLASH_MODE
1271    Parameters::flashMode_t flashMode = flashModeStringToEnum(
1272        newParams.get(CameraParameters::KEY_FLASH_MODE) );
1273    if (flashMode != k.mParameters.flashMode) {
1274        camera_metadata_entry_t flashAvailable =
1275            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1276        if (!flashAvailable.data.u8[0] &&
1277                flashMode != Parameters::FLASH_MODE_OFF) {
1278            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1279                    "No flash on device", __FUNCTION__,
1280                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1281            return BAD_VALUE;
1282        } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1283            camera_metadata_entry_t availableAeModes =
1284                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1285            for (i = 0; i < availableAeModes.count; i++) {
1286                if (flashMode == availableAeModes.data.u8[i]) break;
1287            }
1288            if (i == availableAeModes.count) {
1289                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1290                        __FUNCTION__,
1291                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1292                return BAD_VALUE;
1293            }
1294        } else if (flashMode == -1) {
1295            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1296                    __FUNCTION__,
1297                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1298            return BAD_VALUE;
1299        }
1300    }
1301
1302    // FOCUS_MODE
1303    Parameters::focusMode_t focusMode = focusModeStringToEnum(
1304        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1305    if (focusMode != k.mParameters.focusMode) {
1306        if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1307            camera_metadata_entry_t minFocusDistance =
1308                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1309            if (minFocusDistance.data.f[0] == 0) {
1310                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1311                        "fixed focus lens",
1312                        __FUNCTION__,
1313                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1314                return BAD_VALUE;
1315            } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1316                camera_metadata_entry_t availableFocusModes =
1317                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1318                for (i = 0; i < availableFocusModes.count; i++) {
1319                    if (focusMode == availableFocusModes.data.u8[i]) break;
1320                }
1321                if (i == availableFocusModes.count) {
1322                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1323                            __FUNCTION__,
1324                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1325                    return BAD_VALUE;
1326                }
1327            }
1328        }
1329    }
1330
1331    // FOCUS_AREAS
1332    Vector<Parameters::Area> focusingAreas;
1333    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1334            &focusingAreas);
1335    size_t max3aRegions =
1336        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1337    if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1338    if (res != OK) {
1339        ALOGE("%s: Requested focus areas are malformed: %s",
1340                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1341        return BAD_VALUE;
1342    }
1343
1344    // EXPOSURE_COMPENSATION
1345    int exposureCompensation =
1346        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1347    camera_metadata_entry_t exposureCompensationRange =
1348        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1349    if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1350            exposureCompensation > exposureCompensationRange.data.i32[1]) {
1351        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1352                __FUNCTION__, exposureCompensation);
1353        return BAD_VALUE;
1354    }
1355
1356    // AUTO_EXPOSURE_LOCK (always supported)
1357    bool autoExposureLock = boolFromString(
1358        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1359
1360    // AUTO_WHITEBALANCE_LOCK (always supported)
1361    bool autoWhiteBalanceLock = boolFromString(
1362        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1363
1364    // METERING_AREAS
1365    Vector<Parameters::Area> meteringAreas;
1366    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1367            &meteringAreas);
1368    if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1369    if (res != OK) {
1370        ALOGE("%s: Requested metering areas are malformed: %s",
1371                __FUNCTION__,
1372                newParams.get(CameraParameters::KEY_METERING_AREAS));
1373        return BAD_VALUE;
1374    }
1375
1376    // ZOOM
1377    int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1378    if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1379        ALOGE("%s: Requested zoom level %d is not supported",
1380                __FUNCTION__, zoom);
1381        return BAD_VALUE;
1382    }
1383
1384    // VIDEO_SIZE
1385    int videoWidth, videoHeight;
1386    newParams.getVideoSize(&videoWidth, &videoHeight);
1387    if (videoWidth != k.mParameters.videoWidth ||
1388            videoHeight != k.mParameters.videoHeight) {
1389        if (mState == RECORD) {
1390            ALOGE("%s: Video size cannot be updated when recording is active!",
1391                    __FUNCTION__);
1392            return BAD_VALUE;
1393        }
1394        camera_metadata_entry_t availableVideoSizes =
1395            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1396        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1397            if (availableVideoSizes.data.i32[i] == videoWidth &&
1398                    availableVideoSizes.data.i32[i+1] == videoHeight)  break;
1399        }
1400        if (i == availableVideoSizes.count) {
1401            ALOGE("%s: Requested video size %d x %d is not supported",
1402                    __FUNCTION__, videoWidth, videoHeight);
1403            return BAD_VALUE;
1404        }
1405    }
1406
1407    // RECORDING_HINT (always supported)
1408    bool recordingHint = boolFromString(
1409        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1410
1411    // VIDEO_STABILIZATION
1412    bool videoStabilization = boolFromString(
1413        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1414    camera_metadata_entry_t availableVideoStabilizationModes =
1415        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1416    if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1417        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1418    }
1419
1420    /** Update internal parameters */
1421
1422    k.mParameters.previewWidth = previewWidth;
1423    k.mParameters.previewHeight = previewHeight;
1424    k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1425    k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1426    k.mParameters.previewFps = previewFps;
1427    k.mParameters.previewFormat = previewFormat;
1428
1429    k.mParameters.pictureWidth = pictureWidth;
1430    k.mParameters.pictureHeight = pictureHeight;
1431
1432    k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1433    k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1434    k.mParameters.jpegQuality = jpegQuality;
1435    k.mParameters.jpegThumbQuality = jpegThumbQuality;
1436
1437    k.mParameters.gpsEnabled = gpsEnabled;
1438    k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1439    k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1440    k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1441    k.mParameters.gpsTimestamp = gpsTimestamp;
1442    k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
1443
1444    k.mParameters.wbMode = wbMode;
1445    k.mParameters.effectMode = effectMode;
1446    k.mParameters.antibandingMode = antibandingMode;
1447    k.mParameters.sceneMode = sceneMode;
1448
1449    k.mParameters.flashMode = flashMode;
1450    k.mParameters.focusMode = focusMode;
1451
1452    k.mParameters.focusingAreas = focusingAreas;
1453    k.mParameters.exposureCompensation = exposureCompensation;
1454    k.mParameters.autoExposureLock = autoExposureLock;
1455    k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1456    k.mParameters.meteringAreas = meteringAreas;
1457    k.mParameters.zoom = zoom;
1458
1459    k.mParameters.videoWidth = videoWidth;
1460    k.mParameters.videoHeight = videoHeight;
1461
1462    k.mParameters.recordingHint = recordingHint;
1463    k.mParameters.videoStabilization = videoStabilization;
1464
1465    res = updatePreviewRequest(k.mParameters);
1466    if (res != OK) {
1467        ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1468                __FUNCTION__, mCameraId, strerror(-res), res);
1469        return res;
1470    }
1471    res = updateCaptureRequest(k.mParameters);
1472    if (res != OK) {
1473        ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1474                __FUNCTION__, mCameraId, strerror(-res), res);
1475        return res;
1476    }
1477
1478    res = updateRecordingRequest(k.mParameters);
1479    if (res != OK) {
1480        ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1481                __FUNCTION__, mCameraId, strerror(-res), res);
1482        return res;
1483    }
1484
1485    if (mState == PREVIEW) {
1486        res = mDevice->setStreamingRequest(mPreviewRequest);
1487        if (res != OK) {
1488            ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1489                    __FUNCTION__, mCameraId, strerror(-res), res);
1490            return res;
1491        }
1492    } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1493        res = mDevice->setStreamingRequest(mRecordingRequest);
1494        if (res != OK) {
1495            ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1496                    __FUNCTION__, mCameraId, strerror(-res), res);
1497            return res;
1498        }
1499    }
1500
1501    k.mParameters.paramsFlattened = params;
1502
1503    return OK;
1504}
1505
1506String8 Camera2Client::getParameters() const {
1507    ATRACE_CALL();
1508    Mutex::Autolock icl(mICameraLock);
1509    if ( checkPid(__FUNCTION__) != OK) return String8();
1510
1511    LockedParameters::ReadKey k(mParameters);
1512
1513    // TODO: Deal with focus distances
1514    return k.mParameters.paramsFlattened;
1515}
1516
1517status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
1518    ATRACE_CALL();
1519    Mutex::Autolock icl(mICameraLock);
1520    status_t res;
1521    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1522
1523    ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1524            cmd, arg1, arg2);
1525
1526    switch (cmd) {
1527        case CAMERA_CMD_START_SMOOTH_ZOOM:
1528            return commandStartSmoothZoomL();
1529        case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1530            return commandStopSmoothZoomL();
1531        case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1532            return commandSetDisplayOrientationL(arg1);
1533        case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1534            return commandEnableShutterSoundL(arg1 == 1);
1535        case CAMERA_CMD_PLAY_RECORDING_SOUND:
1536            return commandPlayRecordingSoundL();
1537        case CAMERA_CMD_START_FACE_DETECTION:
1538            return commandStartFaceDetectionL(arg1);
1539        case CAMERA_CMD_STOP_FACE_DETECTION:
1540            return commandStopFaceDetectionL();
1541        case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1542            return commandEnableFocusMoveMsgL(arg1 == 1);
1543        case CAMERA_CMD_PING:
1544            return commandPingL();
1545        case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1546            return commandSetVideoBufferCountL(arg1);
1547        default:
1548            ALOGE("%s: Unknown command %d (arguments %d, %d)",
1549                    __FUNCTION__, cmd, arg1, arg2);
1550            return BAD_VALUE;
1551    }
1552}
1553
1554status_t Camera2Client::commandStartSmoothZoomL() {
1555    ALOGE("%s: Unimplemented!", __FUNCTION__);
1556    return OK;
1557}
1558
1559status_t Camera2Client::commandStopSmoothZoomL() {
1560    ALOGE("%s: Unimplemented!", __FUNCTION__);
1561    return OK;
1562}
1563
1564status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1565    LockedParameters::Key k(mParameters);
1566    int transform = degToTransform(degrees,
1567            mCameraFacing == CAMERA_FACING_FRONT);
1568    if (transform == -1) {
1569        ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1570                __FUNCTION__, mCameraId, degrees);
1571        return BAD_VALUE;
1572    }
1573    if (transform != k.mParameters.previewTransform &&
1574            mPreviewStreamId != NO_STREAM) {
1575        mDevice->setStreamTransform(mPreviewStreamId, transform);
1576    }
1577    k.mParameters.previewTransform = transform;
1578    return OK;
1579}
1580
1581status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1582    LockedParameters::Key k(mParameters);
1583    if (enable) {
1584        k.mParameters.playShutterSound = true;
1585        return OK;
1586    }
1587
1588    // Disabling shutter sound may not be allowed. In that case only
1589    // allow the mediaserver process to disable the sound.
1590    char value[PROPERTY_VALUE_MAX];
1591    property_get("ro.camera.sound.forced", value, "0");
1592    if (strncmp(value, "0", 2) != 0) {
1593        // Disabling shutter sound is not allowed. Deny if the current
1594        // process is not mediaserver.
1595        if (getCallingPid() != getpid()) {
1596            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1597                    getCallingPid());
1598            return PERMISSION_DENIED;
1599        }
1600    }
1601
1602    k.mParameters.playShutterSound = false;
1603    return OK;
1604}
1605
1606status_t Camera2Client::commandPlayRecordingSoundL() {
1607    mCameraService->playSound(CameraService::SOUND_RECORDING);
1608    return OK;
1609}
1610
1611status_t Camera2Client::commandStartFaceDetectionL(int type) {
1612    ALOGE("%s: Unimplemented!", __FUNCTION__);
1613    return OK;
1614}
1615
1616status_t Camera2Client::commandStopFaceDetectionL() {
1617    ALOGE("%s: Unimplemented!", __FUNCTION__);
1618    return OK;
1619}
1620
1621status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
1622    ALOGE("%s: Unimplemented!", __FUNCTION__);
1623    return OK;
1624}
1625
1626status_t Camera2Client::commandPingL() {
1627    // Always ping back if access is proper and device is alive
1628    if (mState != DISCONNECTED) {
1629        return OK;
1630    } else {
1631        return NO_INIT;
1632    }
1633}
1634
1635status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
1636    if (recordingEnabled()) {
1637        ALOGE("%s: Camera %d: Error setting video buffer count after "
1638                "recording was started", __FUNCTION__, mCameraId);
1639        return INVALID_OPERATION;
1640    }
1641
1642    // 32 is the current upper limit on the video buffer count for BufferQueue
1643    if (count > 32) {
1644        ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1645                __FUNCTION__, mCameraId, count);
1646        return BAD_VALUE;
1647    }
1648
1649    // Need to reallocate memory for heap
1650    if (mRecordingHeapCount != count) {
1651        if  (mRecordingHeap != 0) {
1652            mRecordingHeap.clear();
1653            mRecordingHeap = NULL;
1654        }
1655        mRecordingHeapCount = count;
1656    }
1657
1658    return OK;
1659}
1660
1661/** Device-related methods */
1662
1663void Camera2Client::onCaptureAvailable() {
1664    ATRACE_CALL();
1665    status_t res;
1666    sp<ICameraClient> currentClient;
1667    ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1668
1669    CpuConsumer::LockedBuffer imgBuffer;
1670    {
1671        Mutex::Autolock icl(mICameraLock);
1672
1673        // TODO: Signal errors here upstream
1674        if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1675            ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1676                    __FUNCTION__, mCameraId);
1677            return;
1678        }
1679
1680        res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1681        if (res != OK) {
1682            ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1683                    __FUNCTION__, mCameraId, strerror(-res), res);
1684            return;
1685        }
1686
1687        if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1688            ALOGE("%s: Camera %d: Unexpected format for still image: "
1689                    "%x, expected %x", __FUNCTION__, mCameraId,
1690                    imgBuffer.format,
1691                    HAL_PIXEL_FORMAT_BLOB);
1692            mCaptureConsumer->unlockBuffer(imgBuffer);
1693            return;
1694        }
1695
1696        // TODO: Optimize this to avoid memcopy
1697        void* captureMemory = mCaptureHeap->mHeap->getBase();
1698        size_t size = mCaptureHeap->mHeap->getSize();
1699        memcpy(captureMemory, imgBuffer.data, size);
1700
1701        mCaptureConsumer->unlockBuffer(imgBuffer);
1702
1703        currentClient = mCameraClient;
1704        switch (mState) {
1705            case STILL_CAPTURE:
1706                mState = STOPPED;
1707                break;
1708            case VIDEO_SNAPSHOT:
1709                mState = RECORD;
1710                break;
1711            default:
1712                ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1713                        mCameraId, mState);
1714                break;
1715        }
1716    }
1717    // Call outside mICameraLock to allow re-entrancy from notification
1718    if (currentClient != 0) {
1719        currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
1720                mCaptureHeap->mBuffers[0], NULL);
1721    }
1722}
1723
1724void Camera2Client::onRecordingFrameAvailable() {
1725    ATRACE_CALL();
1726    status_t res;
1727    sp<ICameraClient> currentClient;
1728    size_t heapIdx = 0;
1729    nsecs_t timestamp;
1730    {
1731        Mutex::Autolock icl(mICameraLock);
1732        // TODO: Signal errors here upstream
1733        bool discardData = false;
1734        if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
1735            ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1736                    "recording done",
1737                    __FUNCTION__, mCameraId);
1738            discardData = true;
1739        }
1740
1741        buffer_handle_t imgBuffer;
1742        res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
1743        if (res != OK) {
1744            ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1745                    __FUNCTION__, mCameraId, strerror(-res), res);
1746            return;
1747        }
1748
1749        if (discardData) {
1750            mRecordingConsumer->freeBuffer(imgBuffer);
1751            return;
1752        }
1753
1754        if (mRecordingHeap == 0) {
1755            const size_t bufferSize = 4 + sizeof(buffer_handle_t);
1756            ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1757                    "size %d bytes", __FUNCTION__, mCameraId,
1758                    mRecordingHeapCount, bufferSize);
1759            if (mRecordingHeap != 0) {
1760                ALOGV("%s: Camera %d: Previous heap has size %d "
1761                        "(new will be %d) bytes", __FUNCTION__, mCameraId,
1762                        mRecordingHeap->mHeap->getSize(),
1763                        bufferSize * mRecordingHeapCount);
1764            }
1765            // Need to allocate memory for heap
1766            mRecordingHeap.clear();
1767
1768            mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
1769                    "Camera2Client::RecordingHeap");
1770            if (mRecordingHeap->mHeap->getSize() == 0) {
1771                ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1772                        __FUNCTION__, mCameraId);
1773                mRecordingConsumer->freeBuffer(imgBuffer);
1774                return;
1775            }
1776            mRecordingHeapHead = 0;
1777            mRecordingHeapFree = mRecordingHeapCount;
1778        }
1779
1780        if ( mRecordingHeapFree == 0) {
1781            ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1782                    __FUNCTION__, mCameraId);
1783            mRecordingConsumer->freeBuffer(imgBuffer);
1784            return;
1785        }
1786        heapIdx = mRecordingHeapHead;
1787        mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
1788        mRecordingHeapFree--;
1789
1790        ALOGV("%s: Camera %d: Timestamp %lld",
1791                __FUNCTION__, mCameraId, timestamp);
1792
1793        ssize_t offset;
1794        size_t size;
1795        sp<IMemoryHeap> heap =
1796                mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1797                        &size);
1798
1799        uint8_t *data = (uint8_t*)heap->getBase() + offset;
1800        uint32_t type = kMetadataBufferTypeGrallocSource;
1801        memcpy(data, &type, 4);
1802        memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1803        ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
1804                __FUNCTION__, mCameraId, imgBuffer);
1805        currentClient = mCameraClient;
1806    }
1807    // Call outside mICameraLock to allow re-entrancy from notification
1808    if (currentClient != 0) {
1809        currentClient->dataCallbackTimestamp(timestamp,
1810                CAMERA_MSG_VIDEO_FRAME,
1811                mRecordingHeap->mBuffers[heapIdx]);
1812    }
1813}
1814
1815camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1816        size_t minCount, size_t maxCount) {
1817    status_t res;
1818    camera_metadata_entry_t entry;
1819    res = find_camera_metadata_entry(mDevice->info(),
1820            tag,
1821            &entry);
1822    if (CC_UNLIKELY( res != OK )) {
1823        const char* tagSection = get_camera_metadata_section_name(tag);
1824        if (tagSection == NULL) tagSection = "<unknown>";
1825        const char* tagName = get_camera_metadata_tag_name(tag);
1826        if (tagName == NULL) tagName = "<unknown>";
1827
1828        ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1829                tagSection, tagName, tag, strerror(-res), res);
1830        entry.count = 0;
1831        entry.data.u8 = NULL;
1832    } else if (CC_UNLIKELY(
1833            (minCount != 0 && entry.count < minCount) ||
1834            (maxCount != 0 && entry.count > maxCount) ) ) {
1835        const char* tagSection = get_camera_metadata_section_name(tag);
1836        if (tagSection == NULL) tagSection = "<unknown>";
1837        const char* tagName = get_camera_metadata_tag_name(tag);
1838        if (tagName == NULL) tagName = "<unknown>";
1839        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1840                "Expected between %d and %d values, but got %d values",
1841                tagSection, tagName, tag, minCount, maxCount, entry.count);
1842        entry.count = 0;
1843        entry.data.u8 = NULL;
1844    }
1845
1846    return entry;
1847}
1848
1849/** Utility methods */
1850
1851
1852status_t Camera2Client::buildDefaultParameters() {
1853    ATRACE_CALL();
1854    LockedParameters::Key k(mParameters);
1855
1856    status_t res;
1857    CameraParameters params;
1858
1859    camera_metadata_entry_t availableProcessedSizes =
1860        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1861    if (!availableProcessedSizes.count) return NO_INIT;
1862
1863    // TODO: Pick more intelligently
1864    k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1865    k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1866    k.mParameters.videoWidth = k.mParameters.previewWidth;
1867    k.mParameters.videoHeight = k.mParameters.previewHeight;
1868
1869    params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1870    params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
1871    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1872            String8::format("%dx%d",
1873                    k.mParameters.previewWidth, k.mParameters.previewHeight));
1874    {
1875        String8 supportedPreviewSizes;
1876        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1877            if (i != 0) supportedPreviewSizes += ",";
1878            supportedPreviewSizes += String8::format("%dx%d",
1879                    availableProcessedSizes.data.i32[i],
1880                    availableProcessedSizes.data.i32[i+1]);
1881        }
1882        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
1883                supportedPreviewSizes);
1884        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
1885                supportedPreviewSizes);
1886    }
1887
1888    camera_metadata_entry_t availableFpsRanges =
1889        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1890    if (!availableFpsRanges.count) return NO_INIT;
1891
1892    k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1893    k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
1894
1895    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1896            String8::format("%d,%d",
1897                    k.mParameters.previewFpsRange[0],
1898                    k.mParameters.previewFpsRange[1]));
1899
1900    {
1901        String8 supportedPreviewFpsRange;
1902        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1903            if (i != 0) supportedPreviewFpsRange += ",";
1904            supportedPreviewFpsRange += String8::format("(%d,%d)",
1905                    availableFpsRanges.data.i32[i],
1906                    availableFpsRanges.data.i32[i+1]);
1907        }
1908        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
1909                supportedPreviewFpsRange);
1910    }
1911
1912    k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1913    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1914            formatEnumToString(k.mParameters.previewFormat)); // NV21
1915
1916    k.mParameters.previewTransform = degToTransform(0,
1917            mCameraFacing == CAMERA_FACING_FRONT);
1918
1919    camera_metadata_entry_t availableFormats =
1920        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1921
1922    {
1923        String8 supportedPreviewFormats;
1924        bool addComma = false;
1925        for (size_t i=0; i < availableFormats.count; i++) {
1926            if (addComma) supportedPreviewFormats += ",";
1927            addComma = true;
1928            switch (availableFormats.data.i32[i]) {
1929            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1930                supportedPreviewFormats +=
1931                    CameraParameters::PIXEL_FORMAT_YUV422SP;
1932                break;
1933            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1934                supportedPreviewFormats +=
1935                    CameraParameters::PIXEL_FORMAT_YUV420SP;
1936                break;
1937            case HAL_PIXEL_FORMAT_YCbCr_422_I:
1938                supportedPreviewFormats +=
1939                    CameraParameters::PIXEL_FORMAT_YUV422I;
1940                break;
1941            case HAL_PIXEL_FORMAT_YV12:
1942                supportedPreviewFormats +=
1943                    CameraParameters::PIXEL_FORMAT_YUV420P;
1944                break;
1945            case HAL_PIXEL_FORMAT_RGB_565:
1946                supportedPreviewFormats +=
1947                    CameraParameters::PIXEL_FORMAT_RGB565;
1948                break;
1949            case HAL_PIXEL_FORMAT_RGBA_8888:
1950                supportedPreviewFormats +=
1951                    CameraParameters::PIXEL_FORMAT_RGBA8888;
1952                break;
1953            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
1954            case HAL_PIXEL_FORMAT_RAW_SENSOR:
1955            case HAL_PIXEL_FORMAT_BLOB:
1956                addComma = false;
1957                break;
1958
1959            default:
1960                ALOGW("%s: Camera %d: Unknown preview format: %x",
1961                        __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1962                addComma = false;
1963                break;
1964            }
1965        }
1966        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
1967                supportedPreviewFormats);
1968    }
1969
1970    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1971    // still have to do something sane for them
1972
1973    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
1974            k.mParameters.previewFpsRange[0]);
1975
1976    {
1977        String8 supportedPreviewFrameRates;
1978        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1979            if (i != 0) supportedPreviewFrameRates += ",";
1980            supportedPreviewFrameRates += String8::format("%d",
1981                    availableFpsRanges.data.i32[i]);
1982        }
1983        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
1984                supportedPreviewFrameRates);
1985    }
1986
1987    camera_metadata_entry_t availableJpegSizes =
1988        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1989    if (!availableJpegSizes.count) return NO_INIT;
1990
1991    // TODO: Pick maximum
1992    k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1993    k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
1994
1995    params.setPictureSize(k.mParameters.pictureWidth,
1996            k.mParameters.pictureHeight);
1997
1998    {
1999        String8 supportedPictureSizes;
2000        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2001            if (i != 0) supportedPictureSizes += ",";
2002            supportedPictureSizes += String8::format("%dx%d",
2003                    availableJpegSizes.data.i32[i],
2004                    availableJpegSizes.data.i32[i+1]);
2005        }
2006        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
2007                supportedPictureSizes);
2008    }
2009
2010    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2011    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2012            CameraParameters::PIXEL_FORMAT_JPEG);
2013
2014    camera_metadata_entry_t availableJpegThumbnailSizes =
2015        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2016    if (!availableJpegThumbnailSizes.count) return NO_INIT;
2017
2018    // TODO: Pick default thumbnail size sensibly
2019    k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2020    k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
2021
2022    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
2023            k.mParameters.jpegThumbSize[0]);
2024    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
2025            k.mParameters.jpegThumbSize[1]);
2026
2027    {
2028        String8 supportedJpegThumbSizes;
2029        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2030            if (i != 0) supportedJpegThumbSizes += ",";
2031            supportedJpegThumbSizes += String8::format("%dx%d",
2032                    availableJpegThumbnailSizes.data.i32[i],
2033                    availableJpegThumbnailSizes.data.i32[i+1]);
2034        }
2035        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
2036                supportedJpegThumbSizes);
2037    }
2038
2039    k.mParameters.jpegThumbQuality = 90;
2040    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
2041            k.mParameters.jpegThumbQuality);
2042    k.mParameters.jpegQuality = 90;
2043    params.set(CameraParameters::KEY_JPEG_QUALITY,
2044            k.mParameters.jpegQuality);
2045    k.mParameters.jpegRotation = 0;
2046    params.set(CameraParameters::KEY_ROTATION,
2047            k.mParameters.jpegRotation);
2048
2049    k.mParameters.gpsEnabled = false;
2050    k.mParameters.gpsProcessingMethod = "unknown";
2051    // GPS fields in CameraParameters are not set by implementation
2052
2053    k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
2054    params.set(CameraParameters::KEY_WHITE_BALANCE,
2055            CameraParameters::WHITE_BALANCE_AUTO);
2056
2057    camera_metadata_entry_t availableWhiteBalanceModes =
2058        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
2059    {
2060        String8 supportedWhiteBalance;
2061        bool addComma = false;
2062        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2063            if (addComma) supportedWhiteBalance += ",";
2064            addComma = true;
2065            switch (availableWhiteBalanceModes.data.u8[i]) {
2066            case ANDROID_CONTROL_AWB_AUTO:
2067                supportedWhiteBalance +=
2068                    CameraParameters::WHITE_BALANCE_AUTO;
2069                break;
2070            case ANDROID_CONTROL_AWB_INCANDESCENT:
2071                supportedWhiteBalance +=
2072                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
2073                break;
2074            case ANDROID_CONTROL_AWB_FLUORESCENT:
2075                supportedWhiteBalance +=
2076                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
2077                break;
2078            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
2079                supportedWhiteBalance +=
2080                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
2081                break;
2082            case ANDROID_CONTROL_AWB_DAYLIGHT:
2083                supportedWhiteBalance +=
2084                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
2085                break;
2086            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
2087                supportedWhiteBalance +=
2088                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
2089                break;
2090            case ANDROID_CONTROL_AWB_TWILIGHT:
2091                supportedWhiteBalance +=
2092                    CameraParameters::WHITE_BALANCE_TWILIGHT;
2093                break;
2094            case ANDROID_CONTROL_AWB_SHADE:
2095                supportedWhiteBalance +=
2096                    CameraParameters::WHITE_BALANCE_SHADE;
2097                break;
2098            // Skipping values not mappable to v1 API
2099            case ANDROID_CONTROL_AWB_OFF:
2100                addComma = false;
2101                break;
2102            default:
2103                ALOGW("%s: Camera %d: Unknown white balance value: %d",
2104                        __FUNCTION__, mCameraId,
2105                        availableWhiteBalanceModes.data.u8[i]);
2106                addComma = false;
2107                break;
2108            }
2109        }
2110        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
2111                supportedWhiteBalance);
2112    }
2113
2114    k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
2115    params.set(CameraParameters::KEY_EFFECT,
2116            CameraParameters::EFFECT_NONE);
2117
2118    camera_metadata_entry_t availableEffects =
2119        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2120    if (!availableEffects.count) return NO_INIT;
2121    {
2122        String8 supportedEffects;
2123        bool addComma = false;
2124        for (size_t i=0; i < availableEffects.count; i++) {
2125            if (addComma) supportedEffects += ",";
2126            addComma = true;
2127            switch (availableEffects.data.u8[i]) {
2128                case ANDROID_CONTROL_EFFECT_OFF:
2129                    supportedEffects +=
2130                        CameraParameters::EFFECT_NONE;
2131                    break;
2132                case ANDROID_CONTROL_EFFECT_MONO:
2133                    supportedEffects +=
2134                        CameraParameters::EFFECT_MONO;
2135                    break;
2136                case ANDROID_CONTROL_EFFECT_NEGATIVE:
2137                    supportedEffects +=
2138                        CameraParameters::EFFECT_NEGATIVE;
2139                    break;
2140                case ANDROID_CONTROL_EFFECT_SOLARIZE:
2141                    supportedEffects +=
2142                        CameraParameters::EFFECT_SOLARIZE;
2143                    break;
2144                case ANDROID_CONTROL_EFFECT_SEPIA:
2145                    supportedEffects +=
2146                        CameraParameters::EFFECT_SEPIA;
2147                    break;
2148                case ANDROID_CONTROL_EFFECT_POSTERIZE:
2149                    supportedEffects +=
2150                        CameraParameters::EFFECT_POSTERIZE;
2151                    break;
2152                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
2153                    supportedEffects +=
2154                        CameraParameters::EFFECT_WHITEBOARD;
2155                    break;
2156                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
2157                    supportedEffects +=
2158                        CameraParameters::EFFECT_BLACKBOARD;
2159                    break;
2160                case ANDROID_CONTROL_EFFECT_AQUA:
2161                    supportedEffects +=
2162                        CameraParameters::EFFECT_AQUA;
2163                    break;
2164                default:
2165                    ALOGW("%s: Camera %d: Unknown effect value: %d",
2166                        __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2167                    addComma = false;
2168                    break;
2169            }
2170        }
2171        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
2172    }
2173
2174    k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
2175    params.set(CameraParameters::KEY_ANTIBANDING,
2176            CameraParameters::ANTIBANDING_AUTO);
2177
2178    camera_metadata_entry_t availableAntibandingModes =
2179        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2180    if (!availableAntibandingModes.count) return NO_INIT;
2181    {
2182        String8 supportedAntibanding;
2183        bool addComma = false;
2184        for (size_t i=0; i < availableAntibandingModes.count; i++) {
2185            if (addComma) supportedAntibanding += ",";
2186            addComma = true;
2187            switch (availableAntibandingModes.data.u8[i]) {
2188                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
2189                    supportedAntibanding +=
2190                        CameraParameters::ANTIBANDING_OFF;
2191                    break;
2192                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
2193                    supportedAntibanding +=
2194                        CameraParameters::ANTIBANDING_50HZ;
2195                    break;
2196                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
2197                    supportedAntibanding +=
2198                        CameraParameters::ANTIBANDING_60HZ;
2199                    break;
2200                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
2201                    supportedAntibanding +=
2202                        CameraParameters::ANTIBANDING_AUTO;
2203                    break;
2204                default:
2205                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2206                        __FUNCTION__, mCameraId,
2207                            availableAntibandingModes.data.u8[i]);
2208                    addComma = false;
2209                    break;
2210            }
2211        }
2212        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
2213                supportedAntibanding);
2214    }
2215
2216    k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
2217    params.set(CameraParameters::KEY_SCENE_MODE,
2218            CameraParameters::SCENE_MODE_AUTO);
2219
2220    camera_metadata_entry_t availableSceneModes =
2221        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2222    if (!availableSceneModes.count) return NO_INIT;
2223    {
2224        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
2225        bool addComma = true;
2226        bool noSceneModes = false;
2227        for (size_t i=0; i < availableSceneModes.count; i++) {
2228            if (addComma) supportedSceneModes += ",";
2229            addComma = true;
2230            switch (availableSceneModes.data.u8[i]) {
2231                case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2232                    noSceneModes = true;
2233                    break;
2234                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2235                    // Not in old API
2236                    addComma = false;
2237                    break;
2238                case ANDROID_CONTROL_SCENE_MODE_ACTION:
2239                    supportedSceneModes +=
2240                        CameraParameters::SCENE_MODE_ACTION;
2241                    break;
2242                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
2243                    supportedSceneModes +=
2244                        CameraParameters::SCENE_MODE_PORTRAIT;
2245                    break;
2246                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
2247                    supportedSceneModes +=
2248                        CameraParameters::SCENE_MODE_LANDSCAPE;
2249                    break;
2250                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
2251                    supportedSceneModes +=
2252                        CameraParameters::SCENE_MODE_NIGHT;
2253                    break;
2254                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
2255                    supportedSceneModes +=
2256                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
2257                    break;
2258                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
2259                    supportedSceneModes +=
2260                        CameraParameters::SCENE_MODE_THEATRE;
2261                    break;
2262                case ANDROID_CONTROL_SCENE_MODE_BEACH:
2263                    supportedSceneModes +=
2264                        CameraParameters::SCENE_MODE_BEACH;
2265                    break;
2266                case ANDROID_CONTROL_SCENE_MODE_SNOW:
2267                    supportedSceneModes +=
2268                        CameraParameters::SCENE_MODE_SNOW;
2269                    break;
2270                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
2271                    supportedSceneModes +=
2272                        CameraParameters::SCENE_MODE_SUNSET;
2273                    break;
2274                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
2275                    supportedSceneModes +=
2276                        CameraParameters::SCENE_MODE_STEADYPHOTO;
2277                    break;
2278                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
2279                    supportedSceneModes +=
2280                        CameraParameters::SCENE_MODE_FIREWORKS;
2281                    break;
2282                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
2283                    supportedSceneModes +=
2284                        CameraParameters::SCENE_MODE_SPORTS;
2285                    break;
2286                case ANDROID_CONTROL_SCENE_MODE_PARTY:
2287                    supportedSceneModes +=
2288                        CameraParameters::SCENE_MODE_PARTY;
2289                    break;
2290                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
2291                    supportedSceneModes +=
2292                        CameraParameters::SCENE_MODE_CANDLELIGHT;
2293                    break;
2294                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
2295                    supportedSceneModes +=
2296                        CameraParameters::SCENE_MODE_BARCODE;
2297                    break;
2298                default:
2299                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
2300                        __FUNCTION__, mCameraId,
2301                            availableSceneModes.data.u8[i]);
2302                    addComma = false;
2303                    break;
2304            }
2305        }
2306        if (!noSceneModes) {
2307            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
2308                    supportedSceneModes);
2309        }
2310    }
2311
2312    camera_metadata_entry_t flashAvailable =
2313        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2314    if (!flashAvailable.count) return NO_INIT;
2315
2316    camera_metadata_entry_t availableAeModes =
2317        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2318    if (!availableAeModes.count) return NO_INIT;
2319
2320    if (flashAvailable.data.u8[0]) {
2321        k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
2322        params.set(CameraParameters::KEY_FLASH_MODE,
2323                CameraParameters::FLASH_MODE_AUTO);
2324
2325        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2326        supportedFlashModes = supportedFlashModes +
2327            "," + CameraParameters::FLASH_MODE_AUTO +
2328            "," + CameraParameters::FLASH_MODE_ON +
2329            "," + CameraParameters::FLASH_MODE_TORCH;
2330        for (size_t i=0; i < availableAeModes.count; i++) {
2331            if (availableAeModes.data.u8[i] ==
2332                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
2333                supportedFlashModes = supportedFlashModes + "," +
2334                    CameraParameters::FLASH_MODE_RED_EYE;
2335                break;
2336            }
2337        }
2338        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2339                supportedFlashModes);
2340    } else {
2341        k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
2342        params.set(CameraParameters::KEY_FLASH_MODE,
2343                CameraParameters::FLASH_MODE_OFF);
2344        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2345                CameraParameters::FLASH_MODE_OFF);
2346    }
2347
2348    camera_metadata_entry_t minFocusDistance =
2349        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2350    if (!minFocusDistance.count) return NO_INIT;
2351
2352    camera_metadata_entry_t availableAfModes =
2353        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2354    if (!availableAfModes.count) return NO_INIT;
2355
2356    if (minFocusDistance.data.f[0] == 0) {
2357        // Fixed-focus lens
2358        k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
2359        params.set(CameraParameters::KEY_FOCUS_MODE,
2360                CameraParameters::FOCUS_MODE_FIXED);
2361        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2362                CameraParameters::FOCUS_MODE_FIXED);
2363    } else {
2364        k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
2365        params.set(CameraParameters::KEY_FOCUS_MODE,
2366                CameraParameters::FOCUS_MODE_AUTO);
2367        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2368        supportedFocusModes = supportedFocusModes + "," +
2369            CameraParameters::FOCUS_MODE_INFINITY;
2370        bool addComma = true;
2371
2372        for (size_t i=0; i < availableAfModes.count; i++) {
2373            if (addComma) supportedFocusModes += ",";
2374            addComma = true;
2375            switch (availableAfModes.data.u8[i]) {
2376                case ANDROID_CONTROL_AF_AUTO:
2377                    supportedFocusModes +=
2378                        CameraParameters::FOCUS_MODE_AUTO;
2379                    break;
2380                case ANDROID_CONTROL_AF_MACRO:
2381                    supportedFocusModes +=
2382                        CameraParameters::FOCUS_MODE_MACRO;
2383                    break;
2384                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
2385                    supportedFocusModes +=
2386                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
2387                    break;
2388                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
2389                    supportedFocusModes +=
2390                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
2391                    break;
2392                case ANDROID_CONTROL_AF_EDOF:
2393                    supportedFocusModes +=
2394                        CameraParameters::FOCUS_MODE_EDOF;
2395                    break;
2396                // Not supported in old API
2397                case ANDROID_CONTROL_AF_OFF:
2398                    addComma = false;
2399                    break;
2400                default:
2401                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2402                        __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2403                    addComma = false;
2404                    break;
2405            }
2406        }
2407        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2408                supportedFocusModes);
2409    }
2410
2411    camera_metadata_entry_t max3aRegions =
2412        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2413    if (!max3aRegions.count) return NO_INIT;
2414
2415    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
2416            max3aRegions.data.i32[0]);
2417    params.set(CameraParameters::KEY_FOCUS_AREAS,
2418            "(0,0,0,0,0)");
2419    k.mParameters.focusingAreas.clear();
2420    k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
2421
2422    camera_metadata_entry_t availableFocalLengths =
2423        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2424    if (!availableFocalLengths.count) return NO_INIT;
2425
2426    float minFocalLength = availableFocalLengths.data.f[0];
2427    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
2428
2429    camera_metadata_entry_t sensorSize =
2430        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2431    if (!sensorSize.count) return NO_INIT;
2432
2433    // The fields of view here assume infinity focus, maximum wide angle
2434    float horizFov = 180 / M_PI *
2435            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2436    float vertFov  = 180 / M_PI *
2437            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
2438    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2439    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
2440
2441    k.mParameters.exposureCompensation = 0;
2442    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
2443                k.mParameters.exposureCompensation);
2444
2445    camera_metadata_entry_t exposureCompensationRange =
2446        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2447    if (!exposureCompensationRange.count) return NO_INIT;
2448
2449    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
2450            exposureCompensationRange.data.i32[1]);
2451    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
2452            exposureCompensationRange.data.i32[0]);
2453
2454    camera_metadata_entry_t exposureCompensationStep =
2455        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2456    if (!exposureCompensationStep.count) return NO_INIT;
2457
2458    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
2459            (float)exposureCompensationStep.data.r[0].numerator /
2460            exposureCompensationStep.data.r[0].denominator);
2461
2462    k.mParameters.autoExposureLock = false;
2463    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2464            CameraParameters::FALSE);
2465    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2466            CameraParameters::TRUE);
2467
2468    k.mParameters.autoWhiteBalanceLock = false;
2469    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2470            CameraParameters::FALSE);
2471    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2472            CameraParameters::TRUE);
2473
2474    k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
2475    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
2476            max3aRegions.data.i32[0]);
2477    params.set(CameraParameters::KEY_METERING_AREAS,
2478            "(0,0,0,0,0)");
2479
2480    k.mParameters.zoom = 0;
2481    params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
2482    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
2483
2484    camera_metadata_entry_t maxDigitalZoom =
2485        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2486    if (!maxDigitalZoom.count) return NO_INIT;
2487
2488    {
2489        String8 zoomRatios;
2490        float zoom = 1.f;
2491        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
2492                (NUM_ZOOM_STEPS-1);
2493        bool addComma = false;
2494        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
2495            if (addComma) zoomRatios += ",";
2496            addComma = true;
2497            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2498            zoom += zoomIncrement;
2499        }
2500        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
2501    }
2502
2503    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2504            CameraParameters::TRUE);
2505    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2506            CameraParameters::TRUE);
2507
2508    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
2509            "Infinity,Infinity,Infinity");
2510
2511    camera_metadata_entry_t maxFacesDetected =
2512        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2513    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
2514            maxFacesDetected.data.i32[0]);
2515    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
2516            0);
2517
2518    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
2519            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
2520
2521    params.set(CameraParameters::KEY_RECORDING_HINT,
2522            CameraParameters::FALSE);
2523
2524    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2525            CameraParameters::TRUE);
2526
2527    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2528            CameraParameters::FALSE);
2529
2530    camera_metadata_entry_t availableVideoStabilizationModes =
2531        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2532    if (!availableVideoStabilizationModes.count) return NO_INIT;
2533
2534    if (availableVideoStabilizationModes.count > 1) {
2535        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2536                CameraParameters::TRUE);
2537    } else {
2538        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2539                CameraParameters::FALSE);
2540    }
2541
2542    // Set up initial state for non-Camera.Parameters state variables
2543
2544    k.mParameters.storeMetadataInBuffers = true;
2545    k.mParameters.playShutterSound = true;
2546
2547    k.mParameters.paramsFlattened = params.flatten();
2548
2549    return OK;
2550}
2551
2552status_t Camera2Client::updatePreviewStream(const Parameters &params) {
2553    ATRACE_CALL();
2554    status_t res;
2555
2556    if (mPreviewStreamId != NO_STREAM) {
2557        // Check if stream parameters have to change
2558        uint32_t currentWidth, currentHeight;
2559        res = mDevice->getStreamInfo(mPreviewStreamId,
2560                &currentWidth, &currentHeight, 0);
2561        if (res != OK) {
2562            ALOGE("%s: Camera %d: Error querying preview stream info: "
2563                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2564            return res;
2565        }
2566        if (currentWidth != (uint32_t)params.previewWidth ||
2567                currentHeight != (uint32_t)params.previewHeight) {
2568            ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2569                    __FUNCTION__, mCameraId, currentWidth, currentHeight,
2570                    params.previewWidth, params.previewHeight);
2571            res = mDevice->waitUntilDrained();
2572            if (res != OK) {
2573                ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2574                        "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2575                return res;
2576            }
2577            res = mDevice->deleteStream(mPreviewStreamId);
2578            if (res != OK) {
2579                ALOGE("%s: Camera %d: Unable to delete old output stream "
2580                        "for preview: %s (%d)", __FUNCTION__, mCameraId,
2581                        strerror(-res), res);
2582                return res;
2583            }
2584            mPreviewStreamId = NO_STREAM;
2585        }
2586    }
2587
2588    if (mPreviewStreamId == NO_STREAM) {
2589        res = mDevice->createStream(mPreviewWindow,
2590                params.previewWidth, params.previewHeight,
2591                CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2592                &mPreviewStreamId);
2593        if (res != OK) {
2594            ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2595                    __FUNCTION__, mCameraId, strerror(-res), res);
2596            return res;
2597        }
2598    }
2599
2600    res = mDevice->setStreamTransform(mPreviewStreamId,
2601            params.previewTransform);
2602    if (res != OK) {
2603        ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2604                "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2605        return res;
2606    }
2607
2608    return OK;
2609}
2610
2611status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
2612    ATRACE_CALL();
2613    status_t res;
2614    if (mPreviewRequest == NULL) {
2615        res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2616                &mPreviewRequest);
2617        if (res != OK) {
2618            ALOGE("%s: Camera %d: Unable to create default preview request: "
2619                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2620            return res;
2621        }
2622    }
2623
2624    res = updateRequestCommon(mPreviewRequest, params);
2625    if (res != OK) {
2626        ALOGE("%s: Camera %d: Unable to update common entries of preview "
2627                "request: %s (%d)", __FUNCTION__, mCameraId,
2628                strerror(-res), res);
2629        return res;
2630    }
2631
2632    return OK;
2633}
2634
2635status_t Camera2Client::updateCaptureStream(const Parameters &params) {
2636    ATRACE_CALL();
2637    status_t res;
2638    // Find out buffer size for JPEG
2639    camera_metadata_entry_t maxJpegSize =
2640            staticInfo(ANDROID_JPEG_MAX_SIZE);
2641    if (maxJpegSize.count == 0) {
2642        ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2643                __FUNCTION__, mCameraId);
2644        return INVALID_OPERATION;
2645    }
2646
2647    if (mCaptureConsumer == 0) {
2648        // Create CPU buffer queue endpoint
2649        mCaptureConsumer = new CpuConsumer(1);
2650        mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2651        mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2652        mCaptureWindow = new SurfaceTextureClient(
2653            mCaptureConsumer->getProducerInterface());
2654        // Create memory for API consumption
2655        mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2656                                       "Camera2Client::CaptureHeap");
2657        if (mCaptureHeap->mHeap->getSize() == 0) {
2658            ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2659                    __FUNCTION__, mCameraId);
2660            return NO_MEMORY;
2661        }
2662    }
2663
2664    if (mCaptureStreamId != NO_STREAM) {
2665        // Check if stream parameters have to change
2666        uint32_t currentWidth, currentHeight;
2667        res = mDevice->getStreamInfo(mCaptureStreamId,
2668                &currentWidth, &currentHeight, 0);
2669        if (res != OK) {
2670            ALOGE("%s: Camera %d: Error querying capture output stream info: "
2671                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2672            return res;
2673        }
2674        if (currentWidth != (uint32_t)params.pictureWidth ||
2675                currentHeight != (uint32_t)params.pictureHeight) {
2676            res = mDevice->deleteStream(mCaptureStreamId);
2677            if (res != OK) {
2678                ALOGE("%s: Camera %d: Unable to delete old output stream "
2679                        "for capture: %s (%d)", __FUNCTION__, mCameraId,
2680                        strerror(-res), res);
2681                return res;
2682            }
2683            mCaptureStreamId = NO_STREAM;
2684        }
2685    }
2686
2687    if (mCaptureStreamId == NO_STREAM) {
2688        // Create stream for HAL production
2689        res = mDevice->createStream(mCaptureWindow,
2690                params.pictureWidth, params.pictureHeight,
2691                HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2692                &mCaptureStreamId);
2693        if (res != OK) {
2694            ALOGE("%s: Camera %d: Can't create output stream for capture: "
2695                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2696            return res;
2697        }
2698
2699    }
2700    return OK;
2701}
2702
2703status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
2704    ATRACE_CALL();
2705    status_t res;
2706    if (mCaptureRequest == NULL) {
2707        res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2708                &mCaptureRequest);
2709        if (res != OK) {
2710            ALOGE("%s: Camera %d: Unable to create default still image request:"
2711                    " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2712            return res;
2713        }
2714    }
2715
2716    res = updateRequestCommon(mCaptureRequest, params);
2717    if (res != OK) {
2718        ALOGE("%s: Camera %d: Unable to update common entries of capture "
2719                "request: %s (%d)", __FUNCTION__, mCameraId,
2720                strerror(-res), res);
2721        return res;
2722    }
2723
2724    res = updateEntry(mCaptureRequest,
2725            ANDROID_JPEG_THUMBNAIL_SIZE,
2726            params.jpegThumbSize, 2);
2727    if (res != OK) return res;
2728    res = updateEntry(mCaptureRequest,
2729            ANDROID_JPEG_THUMBNAIL_QUALITY,
2730            &params.jpegThumbQuality, 1);
2731    if (res != OK) return res;
2732    res = updateEntry(mCaptureRequest,
2733            ANDROID_JPEG_QUALITY,
2734            &params.jpegQuality, 1);
2735    if (res != OK) return res;
2736    res = updateEntry(mCaptureRequest,
2737            ANDROID_JPEG_ORIENTATION,
2738            &params.jpegRotation, 1);
2739    if (res != OK) return res;
2740
2741    if (params.gpsEnabled) {
2742        res = updateEntry(mCaptureRequest,
2743                ANDROID_JPEG_GPS_COORDINATES,
2744                params.gpsCoordinates, 3);
2745        if (res != OK) return res;
2746        res = updateEntry(mCaptureRequest,
2747                ANDROID_JPEG_GPS_TIMESTAMP,
2748                &params.gpsTimestamp, 1);
2749        if (res != OK) return res;
2750        res = updateEntry(mCaptureRequest,
2751                ANDROID_JPEG_GPS_PROCESSING_METHOD,
2752                params.gpsProcessingMethod.string(),
2753                params.gpsProcessingMethod.size());
2754        if (res != OK) return res;
2755    } else {
2756        res = deleteEntry(mCaptureRequest,
2757                ANDROID_JPEG_GPS_COORDINATES);
2758        if (res != OK) return res;
2759        res = deleteEntry(mCaptureRequest,
2760                ANDROID_JPEG_GPS_TIMESTAMP);
2761        if (res != OK) return res;
2762        res = deleteEntry(mCaptureRequest,
2763                ANDROID_JPEG_GPS_PROCESSING_METHOD);
2764        if (res != OK) return res;
2765    }
2766
2767    return OK;
2768}
2769
2770status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
2771    ATRACE_CALL();
2772    status_t res;
2773    if (mRecordingRequest == NULL) {
2774        res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2775                &mRecordingRequest);
2776        if (res != OK) {
2777            ALOGE("%s: Camera %d: Unable to create default recording request:"
2778                    " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2779            return res;
2780        }
2781    }
2782
2783    res = updateRequestCommon(mRecordingRequest, params);
2784    if (res != OK) {
2785        ALOGE("%s: Camera %d: Unable to update common entries of recording "
2786                "request: %s (%d)", __FUNCTION__, mCameraId,
2787                strerror(-res), res);
2788        return res;
2789    }
2790
2791    return OK;
2792}
2793
2794status_t Camera2Client::updateRecordingStream(const Parameters &params) {
2795    status_t res;
2796
2797    if (mRecordingConsumer == 0) {
2798        // Create CPU buffer queue endpoint
2799        mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
2800        mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2801        mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2802        mRecordingWindow = new SurfaceTextureClient(
2803            mRecordingConsumer->getProducerInterface());
2804        // Allocate memory later, since we don't know buffer size until receipt
2805    }
2806
2807    if (mRecordingStreamId != NO_STREAM) {
2808        // Check if stream parameters have to change
2809        uint32_t currentWidth, currentHeight;
2810        res = mDevice->getStreamInfo(mRecordingStreamId,
2811                &currentWidth, &currentHeight, 0);
2812        if (res != OK) {
2813            ALOGE("%s: Camera %d: Error querying recording output stream info: "
2814                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2815            return res;
2816        }
2817        if (currentWidth != (uint32_t)params.videoWidth ||
2818                currentHeight != (uint32_t)params.videoHeight) {
2819            // TODO: Should wait to be sure previous recording has finished
2820            res = mDevice->deleteStream(mRecordingStreamId);
2821            if (res != OK) {
2822                ALOGE("%s: Camera %d: Unable to delete old output stream "
2823                        "for recording: %s (%d)", __FUNCTION__, mCameraId,
2824                        strerror(-res), res);
2825                return res;
2826            }
2827            mRecordingStreamId = NO_STREAM;
2828        }
2829    }
2830
2831    if (mRecordingStreamId == NO_STREAM) {
2832        res = mDevice->createStream(mRecordingWindow,
2833                params.videoWidth, params.videoHeight,
2834                CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
2835        if (res != OK) {
2836            ALOGE("%s: Camera %d: Can't create output stream for recording: "
2837                    "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2838            return res;
2839        }
2840    }
2841
2842    return OK;
2843}
2844
2845status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2846        const Parameters &params) {
2847    ATRACE_CALL();
2848    status_t res;
2849    res = updateEntry(request,
2850            ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
2851    if (res != OK) return res;
2852
2853    uint8_t wbMode = params.autoWhiteBalanceLock ?
2854            ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
2855    res = updateEntry(request,
2856            ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2857    if (res != OK) return res;
2858    res = updateEntry(request,
2859            ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
2860    if (res != OK) return res;
2861    res = updateEntry(request,
2862            ANDROID_CONTROL_AE_ANTIBANDING_MODE,
2863            &params.antibandingMode, 1);
2864    if (res != OK) return res;
2865
2866    uint8_t controlMode =
2867            (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
2868            ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2869    res = updateEntry(request,
2870            ANDROID_CONTROL_MODE, &controlMode, 1);
2871    if (res != OK) return res;
2872    if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2873        res = updateEntry(request,
2874                ANDROID_CONTROL_SCENE_MODE,
2875                &params.sceneMode, 1);
2876        if (res != OK) return res;
2877    }
2878
2879    uint8_t flashMode = ANDROID_FLASH_OFF;
2880    uint8_t aeMode;
2881    switch (params.flashMode) {
2882        case Parameters::FLASH_MODE_OFF:
2883            aeMode = ANDROID_CONTROL_AE_ON; break;
2884        case Parameters::FLASH_MODE_AUTO:
2885            aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2886        case Parameters::FLASH_MODE_ON:
2887            aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2888        case Parameters::FLASH_MODE_TORCH:
2889            aeMode = ANDROID_CONTROL_AE_ON;
2890            flashMode = ANDROID_FLASH_TORCH;
2891            break;
2892        case Parameters::FLASH_MODE_RED_EYE:
2893            aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2894        default:
2895            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
2896                    mCameraId, params.flashMode);
2897            return BAD_VALUE;
2898    }
2899    if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
2900
2901    res = updateEntry(request,
2902            ANDROID_FLASH_MODE, &flashMode, 1);
2903    if (res != OK) return res;
2904    res = updateEntry(request,
2905            ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2906    if (res != OK) return res;
2907
2908    float focusDistance = 0; // infinity focus in diopters
2909    uint8_t focusMode;
2910    switch (params.focusMode) {
2911        case Parameters::FOCUS_MODE_AUTO:
2912        case Parameters::FOCUS_MODE_MACRO:
2913        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2914        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2915        case Parameters::FOCUS_MODE_EDOF:
2916            focusMode = params.focusMode;
2917            break;
2918        case Parameters::FOCUS_MODE_INFINITY:
2919        case Parameters::FOCUS_MODE_FIXED:
2920            focusMode = ANDROID_CONTROL_AF_OFF;
2921            break;
2922        default:
2923            ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
2924                    mCameraId, params.focusMode);
2925            return BAD_VALUE;
2926    }
2927    res = updateEntry(request,
2928            ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2929    if (res != OK) return res;
2930    res = updateEntry(request,
2931            ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2932    if (res != OK) return res;
2933
2934    size_t focusingAreasSize = params.focusingAreas.size() * 5;
2935    int32_t *focusingAreas = new int32_t[focusingAreasSize];
2936    for (size_t i = 0; i < focusingAreasSize; i += 5) {
2937        focusingAreas[i + 0] = params.focusingAreas[i].left;
2938        focusingAreas[i + 1] = params.focusingAreas[i].top;
2939        focusingAreas[i + 2] = params.focusingAreas[i].right;
2940        focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2941        focusingAreas[i + 4] = params.focusingAreas[i].weight;
2942    }
2943    res = updateEntry(request,
2944            ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2945    if (res != OK) return res;
2946    delete[] focusingAreas;
2947
2948    res = updateEntry(request,
2949            ANDROID_CONTROL_AE_EXP_COMPENSATION,
2950            &params.exposureCompensation, 1);
2951    if (res != OK) return res;
2952
2953    size_t meteringAreasSize = params.meteringAreas.size() * 5;
2954    int32_t *meteringAreas = new int32_t[meteringAreasSize];
2955    for (size_t i = 0; i < meteringAreasSize; i += 5) {
2956        meteringAreas[i + 0] = params.meteringAreas[i].left;
2957        meteringAreas[i + 1] = params.meteringAreas[i].top;
2958        meteringAreas[i + 2] = params.meteringAreas[i].right;
2959        meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2960        meteringAreas[i + 4] = params.meteringAreas[i].weight;
2961    }
2962    res = updateEntry(request,
2963            ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2964    if (res != OK) return res;
2965
2966    res = updateEntry(request,
2967            ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2968    if (res != OK) return res;
2969    delete[] meteringAreas;
2970
2971    // Need to convert zoom index into a crop rectangle. The rectangle is
2972    // chosen to maximize its area on the sensor
2973
2974    camera_metadata_entry_t maxDigitalZoom =
2975            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2976    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2977            (NUM_ZOOM_STEPS-1);
2978    float zoomRatio = 1 + zoomIncrement * params.zoom;
2979
2980    camera_metadata_entry_t activePixelArraySize =
2981            staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2982    int32_t arrayWidth = activePixelArraySize.data.i32[0];
2983    int32_t arrayHeight = activePixelArraySize.data.i32[1];
2984    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2985    if (params.previewWidth >= params.previewHeight) {
2986        zoomWidth =  arrayWidth / zoomRatio;
2987        zoomHeight = zoomWidth *
2988                params.previewHeight / params.previewWidth;
2989    } else {
2990        zoomHeight = arrayHeight / zoomRatio;
2991        zoomWidth = zoomHeight *
2992                params.previewWidth / params.previewHeight;
2993    }
2994    zoomLeft = (arrayWidth - zoomWidth) / 2;
2995    zoomTop = (arrayHeight - zoomHeight) / 2;
2996
2997    int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2998    res = updateEntry(request,
2999            ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3000    if (res != OK) return res;
3001
3002    // TODO: Decide how to map recordingHint, or whether just to ignore it
3003
3004    uint8_t vstabMode = params.videoStabilization ?
3005            ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3006            ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3007    res = updateEntry(request,
3008            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3009            &vstabMode, 1);
3010    if (res != OK) return res;
3011
3012    return OK;
3013}
3014
3015status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3016        uint32_t tag, const void *data, size_t data_count) {
3017    camera_metadata_entry_t entry;
3018    status_t res;
3019    res = find_camera_metadata_entry(buffer, tag, &entry);
3020    if (res == NAME_NOT_FOUND) {
3021        res = add_camera_metadata_entry(buffer,
3022                tag, data, data_count);
3023    } else if (res == OK) {
3024        res = update_camera_metadata_entry(buffer,
3025                entry.index, data, data_count, NULL);
3026    }
3027
3028    if (res != OK) {
3029        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3030                __FUNCTION__, get_camera_metadata_section_name(tag),
3031                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3032    }
3033    return res;
3034}
3035
3036status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3037    camera_metadata_entry_t entry;
3038    status_t res;
3039    res = find_camera_metadata_entry(buffer, tag, &entry);
3040    if (res == NAME_NOT_FOUND) {
3041        return OK;
3042    } else if (res != OK) {
3043        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3044                __FUNCTION__,
3045                get_camera_metadata_section_name(tag),
3046                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3047        return res;
3048    }
3049    res = delete_camera_metadata_entry(buffer, entry.index);
3050    if (res != OK) {
3051        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3052                __FUNCTION__,
3053                get_camera_metadata_section_name(tag),
3054                get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3055    }
3056    return res;
3057}
3058
3059int Camera2Client::formatStringToEnum(const char *format) {
3060    return
3061        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3062            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3063        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3064            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3065        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3066            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
3067        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3068            HAL_PIXEL_FORMAT_YV12 :         // YV12
3069        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3070            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
3071        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3072            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
3073        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3074            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
3075        -1;
3076}
3077
3078const char* Camera2Client::formatEnumToString(int format) {
3079    const char *fmt;
3080    switch(format) {
3081        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3082            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3083            break;
3084        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3085            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3086            break;
3087        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3088            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3089            break;
3090        case HAL_PIXEL_FORMAT_YV12:        // YV12
3091            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3092            break;
3093        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
3094            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3095            break;
3096        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
3097            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3098            break;
3099        case HAL_PIXEL_FORMAT_RAW_SENSOR:
3100            ALOGW("Raw sensor preview format requested.");
3101            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3102            break;
3103        default:
3104            ALOGE("%s: Unknown preview format: %x",
3105                    __FUNCTION__,  format);
3106            fmt = NULL;
3107            break;
3108    }
3109    return fmt;
3110}
3111
3112int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3113    return
3114        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3115            ANDROID_CONTROL_AWB_AUTO :
3116        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3117            ANDROID_CONTROL_AWB_INCANDESCENT :
3118        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3119            ANDROID_CONTROL_AWB_FLUORESCENT :
3120        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3121            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3122        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3123            ANDROID_CONTROL_AWB_DAYLIGHT :
3124        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3125            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3126        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3127            ANDROID_CONTROL_AWB_TWILIGHT :
3128        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3129            ANDROID_CONTROL_AWB_SHADE :
3130        -1;
3131}
3132
3133int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3134    return
3135        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3136            ANDROID_CONTROL_EFFECT_OFF :
3137        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3138            ANDROID_CONTROL_EFFECT_MONO :
3139        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3140            ANDROID_CONTROL_EFFECT_NEGATIVE :
3141        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3142            ANDROID_CONTROL_EFFECT_SOLARIZE :
3143        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3144            ANDROID_CONTROL_EFFECT_SEPIA :
3145        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3146            ANDROID_CONTROL_EFFECT_POSTERIZE :
3147        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3148            ANDROID_CONTROL_EFFECT_WHITEBOARD :
3149        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3150            ANDROID_CONTROL_EFFECT_BLACKBOARD :
3151        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3152            ANDROID_CONTROL_EFFECT_AQUA :
3153        -1;
3154}
3155
3156int Camera2Client::abModeStringToEnum(const char *abMode) {
3157    return
3158        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3159            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3160        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3161            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3162        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3163            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3164        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3165            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3166        -1;
3167}
3168
3169int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3170    return
3171        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3172            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3173        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3174            ANDROID_CONTROL_SCENE_MODE_ACTION :
3175        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3176            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3177        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3178            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3179        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3180            ANDROID_CONTROL_SCENE_MODE_NIGHT :
3181        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3182            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3183        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3184            ANDROID_CONTROL_SCENE_MODE_THEATRE :
3185        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3186            ANDROID_CONTROL_SCENE_MODE_BEACH :
3187        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3188            ANDROID_CONTROL_SCENE_MODE_SNOW :
3189        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3190            ANDROID_CONTROL_SCENE_MODE_SUNSET :
3191        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3192            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3193        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3194            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3195        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3196            ANDROID_CONTROL_SCENE_MODE_SPORTS :
3197        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3198            ANDROID_CONTROL_SCENE_MODE_PARTY :
3199        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3200            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3201        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3202            ANDROID_CONTROL_SCENE_MODE_BARCODE:
3203        -1;
3204}
3205
3206Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3207        const char *flashMode) {
3208    return
3209        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3210            Parameters::FLASH_MODE_OFF :
3211        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3212            Parameters::FLASH_MODE_AUTO :
3213        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3214            Parameters::FLASH_MODE_ON :
3215        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3216            Parameters::FLASH_MODE_RED_EYE :
3217        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3218            Parameters::FLASH_MODE_TORCH :
3219        Parameters::FLASH_MODE_INVALID;
3220}
3221
3222Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3223        const char *focusMode) {
3224    return
3225        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3226            Parameters::FOCUS_MODE_AUTO :
3227        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3228            Parameters::FOCUS_MODE_INFINITY :
3229        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3230            Parameters::FOCUS_MODE_MACRO :
3231        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3232            Parameters::FOCUS_MODE_FIXED :
3233        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3234            Parameters::FOCUS_MODE_EDOF :
3235        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3236            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3237        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3238            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3239        Parameters::FOCUS_MODE_INVALID;
3240}
3241
3242status_t Camera2Client::parseAreas(const char *areasCStr,
3243        Vector<Parameters::Area> *areas) {
3244    static const size_t NUM_FIELDS = 5;
3245    areas->clear();
3246    if (areasCStr == NULL) {
3247        // If no key exists, use default (0,0,0,0,0)
3248        areas->push();
3249        return OK;
3250    }
3251    String8 areasStr(areasCStr);
3252    ssize_t areaStart = areasStr.find("(", 0) + 1;
3253    while (areaStart != 0) {
3254        const char* area = areasStr.string() + areaStart;
3255        char *numEnd;
3256        int vals[NUM_FIELDS];
3257        for (size_t i = 0; i < NUM_FIELDS; i++) {
3258            errno = 0;
3259            vals[i] = strtol(area, &numEnd, 10);
3260            if (errno || numEnd == area) return BAD_VALUE;
3261            area = numEnd + 1;
3262        }
3263        areas->push(Parameters::Area(
3264            vals[0], vals[1], vals[2], vals[3], vals[4]) );
3265        areaStart = areasStr.find("(", areaStart) + 1;
3266    }
3267    return OK;
3268}
3269
3270status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3271                                      size_t maxRegions) {
3272    // Definition of valid area can be found in
3273    // include/camera/CameraParameters.h
3274    if (areas.size() == 0) return BAD_VALUE;
3275    if (areas.size() == 1) {
3276        if (areas[0].left == 0 &&
3277                areas[0].top == 0 &&
3278                areas[0].right == 0 &&
3279                areas[0].bottom == 0 &&
3280                areas[0].weight == 0) {
3281            // Single (0,0,0,0,0) entry is always valid (== driver decides)
3282            return OK;
3283        }
3284    }
3285    if (areas.size() > maxRegions) {
3286        ALOGE("%s: Too many areas requested: %d",
3287                __FUNCTION__, areas.size());
3288        return BAD_VALUE;
3289    }
3290
3291    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3292         a != areas.end(); a++) {
3293        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3294        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3295        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3296        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3297        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3298        if (a->left >= a->right) return BAD_VALUE;
3299        if (a->top >= a->bottom) return BAD_VALUE;
3300    }
3301    return OK;
3302}
3303
3304bool Camera2Client::boolFromString(const char *boolStr) {
3305    return !boolStr ? false :
3306        !strcmp(boolStr, CameraParameters::TRUE) ? true :
3307        false;
3308}
3309
3310int Camera2Client::degToTransform(int degrees, bool mirror) {
3311    if (!mirror) {
3312        if (degrees == 0) return 0;
3313        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3314        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3315        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3316    } else {  // Do mirror (horizontal flip)
3317        if (degrees == 0) {           // FLIP_H and ROT_0
3318            return HAL_TRANSFORM_FLIP_H;
3319        } else if (degrees == 90) {   // FLIP_H and ROT_90
3320            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3321        } else if (degrees == 180) {  // FLIP_H and ROT_180
3322            return HAL_TRANSFORM_FLIP_V;
3323        } else if (degrees == 270) {  // FLIP_H and ROT_270
3324            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3325        }
3326    }
3327    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3328    return -1;
3329}
3330
3331} // namespace android
3332