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