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