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