1d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams/*
2d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Copyright (C) 2012 The Android Open Source Project
3d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
4d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * you may not use this file except in compliance with the License.
6d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * You may obtain a copy of the License at
7d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
8d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
10d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Unless required by applicable law or agreed to in writing, software
11d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * See the License for the specific language governing permissions and
14d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * limitations under the License.
15d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams */
16d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
17f29ca50d80e3dc379de1642e85b7963175b2ca38Jason Sams#define LOG_TAG "CameraClient"
18f29ca50d80e3dc379de1642e85b7963175b2ca38Jason Sams//#define LOG_NDEBUG 0
19d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
20d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include <cutils/properties.h>
21d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include <gui/Surface.h>
22d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include <media/hardware/HardwareAPI.h>
23d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
24d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "api1/CameraClient.h"
25d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "device1/CameraHardwareInterface.h"
26000479f9e325b4e426a67033abd92d47da412725Mathias Agopian#include "CameraService.h"
27d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
28ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Samsnamespace android {
29650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
30650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
31650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
32650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
33ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Samsstatic int getCallingPid() {
34650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy    return IPCThreadState::self()->getCallingPid();
35b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk}
36650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
37f29ca50d80e3dc379de1642e85b7963175b2ca38Jason SamsCameraClient::CameraClient(const sp<CameraService>& cameraService,
38d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        const sp<hardware::ICameraClient>& cameraClient,
39d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        const String16& clientPackageName,
40d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        int cameraId, int cameraFacing,
41ee956053d6e3f7a7a82e41853b9b251fdc226d7aJim Miller        int clientPid, int clientUid,
42b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        int servicePid, bool legacyMode):
43d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        Client(cameraService, cameraClient, clientPackageName,
44e29d471e5ca9781d8772d445ec7832e94856fd14Jason Sams                cameraId, cameraFacing, clientPid, clientUid, servicePid)
45e29d471e5ca9781d8772d445ec7832e94856fd14Jason Sams{
46d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    int callingPid = getCallingPid();
47d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
48d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
49d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mHardware = NULL;
50d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mMsgEnabled = 0;
51d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mSurface = 0;
52b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mPreviewWindow = 0;
53b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mDestructionStarted = false;
54b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
55b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    // Callback is disabled by default
56b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
57b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
58b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mLegacyMode = legacyMode;
59b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mPlayShutterSound = true;
60b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
61b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk}
62b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
63b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchoukstatus_t CameraClient::initialize(CameraModule *module) {
64b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    int callingPid = getCallingPid();
65b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    status_t res;
66b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
67b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
68b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
69b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    // Verify ops permissions
70b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    res = startCameraOps();
71b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    if (res != OK) {
72b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        return res;
73d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
74d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
75ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams    char camera_device_name[10];
76ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams    snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
7743ee06857bb7f99446d1d84f8789016c5d105558Jason Sams
78d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mHardware = new CameraHardwareInterface(camera_device_name);
79d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    res = mHardware->initialize(module);
80d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (res != OK) {
81d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
82ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams                __FUNCTION__, mCameraId, strerror(-res), res);
83ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams        mHardware.clear();
84ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams        return res;
85d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
86d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
87d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mHardware->setCallbacks(notifyCallback,
88d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            dataCallback,
893eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams            dataCallbackTimestamp,
902e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams            (void *)(uintptr_t)mCameraId);
9196ed4cfa62dd09aafb3f9da01e047661b4fe3c95Jason Sams
9296ed4cfa62dd09aafb3f9da01e047661b4fe3c95Jason Sams    // Enable zoom, error, focus, and metadata messages by default
9396ed4cfa62dd09aafb3f9da01e047661b4fe3c95Jason Sams    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
9496ed4cfa62dd09aafb3f9da01e047661b4fe3c95Jason Sams                  CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
9596ed4cfa62dd09aafb3f9da01e047661b4fe3c95Jason Sams
9696ed4cfa62dd09aafb3f9da01e047661b4fe3c95Jason Sams    LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
972e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    return OK;
983eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams}
9907ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams
1003eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams
1013eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams// tear down the client
102bc948dedcee57a66fe2cb38d4c79d04a10c7efb3Jason SamsCameraClient::~CameraClient() {
1033eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams    mDestructionStarted = true;
1043eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams    int callingPid = getCallingPid();
1053eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams    LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
106fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchouk
1072e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    disconnect();
108fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchouk    LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
109fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchouk}
110fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchouk
111581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchoukstatus_t CameraClient::dump(int fd, const Vector<String16>& args) {
112581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk    return BasicClient::dump(fd, args);
113581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk}
114581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk
115fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchoukstatus_t CameraClient::dumpClient(int fd, const Vector<String16>& args) {
116fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchouk    const size_t SIZE = 256;
117fb10c16a0528a418053e4b8e75eebe57476b86efAlex Sakhartchouk    char buffer[SIZE];
1187ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams
1192e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) with UID %d\n",
1207ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams            mCameraId,
1217ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams            (getRemoteCallback() != NULL ?
1229c25aee52672f9c8908e062bde502341c189970eJason Sams                    IInterface::asBinder(getRemoteCallback()).get() : NULL),
1237ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams            mClientUid);
1247ce033d797e5df5e2131e2ed459fba181eaf4658Jason Sams    len = (len > SIZE - 1) ? SIZE - 1 : len;
1253eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams    write(fd, buffer, len);
1263eaa338e11a3b0d6b87d705e5bb95625e82347bdJason Sams
127d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    len = snprintf(buffer, SIZE, "Latest set parameters:\n");
128d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    len = (len > SIZE - 1) ? SIZE - 1 : len;
129d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    write(fd, buffer, len);
130d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
131d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mLatestSetParameters.dump(fd, args);
132d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
133d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    const char *enddump = "\n\n";
134d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    write(fd, enddump, strlen(enddump));
135d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
136d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    return mHardware->dump(fd, args);
137d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
138d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
139d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams// ----------------------------------------------------------------------------
140d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
141ebfb436a49673693b98469683451bd9ede797557Jason Samsstatus_t CameraClient::checkPid() const {
142ebfb436a49673693b98469683451bd9ede797557Jason Sams    int callingPid = getCallingPid();
143ebfb436a49673693b98469683451bd9ede797557Jason Sams    if (callingPid == mClientPid) return NO_ERROR;
144ebfb436a49673693b98469683451bd9ede797557Jason Sams
145ebfb436a49673693b98469683451bd9ede797557Jason Sams    ALOGW("attempt to use a locked camera from a different process"
146ebfb436a49673693b98469683451bd9ede797557Jason Sams         " (old pid %d, new pid %d)", mClientPid, callingPid);
147ebfb436a49673693b98469683451bd9ede797557Jason Sams    return EBUSY;
148d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
149704ff64b099406bb328898a7443921f22dbffd6dJason Sams
150d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsstatus_t CameraClient::checkPidAndHardware() const {
151d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (mHardware == 0) {
152704ff64b099406bb328898a7443921f22dbffd6dJason Sams        ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
153704ff64b099406bb328898a7443921f22dbffd6dJason Sams        return INVALID_OPERATION;
154704ff64b099406bb328898a7443921f22dbffd6dJason Sams    }
155704ff64b099406bb328898a7443921f22dbffd6dJason Sams    status_t result = checkPid();
15611c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    if (result != NO_ERROR) return result;
15711c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    return NO_ERROR;
15811c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams}
15911c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams
16011c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Samsstatus_t CameraClient::lock() {
1612c74ad9aae29cc64fece926f353825a7925792c2Alex Sakhartchouk    int callingPid = getCallingPid();
1622c74ad9aae29cc64fece926f353825a7925792c2Alex Sakhartchouk    LOG1("lock (pid %d)", callingPid);
16311c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    Mutex::Autolock lock(mLock);
16411c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams
16511c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    // lock camera to this client if the the camera is unlocked
16611c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    if (mClientPid == 0) {
16711c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams        mClientPid = callingPid;
16811c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams        return NO_ERROR;
16911c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    }
17011c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams
17111c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
17211c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    return checkPid();
17311c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams}
17411c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams
175704ff64b099406bb328898a7443921f22dbffd6dJason Samsstatus_t CameraClient::unlock() {
1762c74ad9aae29cc64fece926f353825a7925792c2Alex Sakhartchouk    int callingPid = getCallingPid();
177d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    LOG1("unlock (pid %d)", callingPid);
178d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Mutex::Autolock lock(mLock);
179d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
1802e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    // allow anyone to use camera (after they lock the camera)
1817d787b4722eaeb79cab42c36060336e092b77b5fJason Sams    status_t result = checkPid();
1827d787b4722eaeb79cab42c36060336e092b77b5fJason Sams    if (result == NO_ERROR) {
1837d787b4722eaeb79cab42c36060336e092b77b5fJason Sams        if (mHardware->recordingEnabled()) {
1847d787b4722eaeb79cab42c36060336e092b77b5fJason Sams            ALOGE("Not allowed to unlock camera during recording.");
1857d787b4722eaeb79cab42c36060336e092b77b5fJason Sams            return INVALID_OPERATION;
1867d787b4722eaeb79cab42c36060336e092b77b5fJason Sams        }
1877d787b4722eaeb79cab42c36060336e092b77b5fJason Sams        mClientPid = 0;
1887d787b4722eaeb79cab42c36060336e092b77b5fJason Sams        LOG1("clear mRemoteCallback (pid %d)", callingPid);
1892e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        // we need to remove the reference to ICameraClient so that when the app
190efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams        // goes away, the reference count goes to 0.
1913bc47d438171dce294e816366d53bc9eca772c5bJason Sams        mRemoteCallback.clear();
192efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams    }
193efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams    return result;
194efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams}
195efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams
196efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams// connect a new client to the camera
197ee956053d6e3f7a7a82e41853b9b251fdc226d7aJim Millerstatus_t CameraClient::connect(const sp<hardware::ICameraClient>& client) {
198efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams    int callingPid = getCallingPid();
199efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams    LOG1("connect E (pid %d)", callingPid);
200e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    Mutex::Autolock lock(mLock);
201efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams
202efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams    if (mClientPid != 0 && checkPid() != NO_ERROR) {
203efd9b6fb2e0f31b50db089352118e5daeb268879Jason Sams        ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
2042e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams                mClientPid, callingPid);
205d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return EBUSY;
2062e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    }
2072e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams
208d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (mRemoteCallback != 0 &&
209d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        (IInterface::asBinder(client) == IInterface::asBinder(mRemoteCallback))) {
210715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams        LOG1("Connect to the same client");
2112e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        return NO_ERROR;
212715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    }
213715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams
214715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
215715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    mClientPid = callingPid;
216d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mRemoteCallback = client;
217d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
2182e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    LOG1("connect X (pid %d)", callingPid);
21965e7aa56f56097418d617663683544c25b3988eaJason Sams    return NO_ERROR;
22065e7aa56f56097418d617663683544c25b3988eaJason Sams}
22165e7aa56f56097418d617663683544c25b3988eaJason Sams
22265e7aa56f56097418d617663683544c25b3988eaJason Samsstatic void disconnectWindow(const sp<ANativeWindow>& window) {
22365e7aa56f56097418d617663683544c25b3988eaJason Sams    if (window != 0) {
22465e7aa56f56097418d617663683544c25b3988eaJason Sams        status_t result = native_window_api_disconnect(window.get(),
2252e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams                NATIVE_WINDOW_API_CAMERA);
22665e7aa56f56097418d617663683544c25b3988eaJason Sams        if (result != NO_ERROR) {
22765e7aa56f56097418d617663683544c25b3988eaJason Sams            ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
22865e7aa56f56097418d617663683544c25b3988eaJason Sams                    result);
22965e7aa56f56097418d617663683544c25b3988eaJason Sams        }
23065e7aa56f56097418d617663683544c25b3988eaJason Sams    }
2311c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams}
2321c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
2331c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Samsbinder::Status CameraClient::disconnect() {
2341c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    int callingPid = getCallingPid();
2351c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    LOG1("disconnect E (pid %d)", callingPid);
2361c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    Mutex::Autolock lock(mLock);
2371c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
2381c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    binder::Status res = binder::Status::ok();
2391c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    // Allow both client and the cameraserver to disconnect at all times
24065bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    if (callingPid != mClientPid && callingPid != mServicePid) {
24165bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams        ALOGW("different client - don't disconnect");
24265bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams        return res;
24365bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    }
24465bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams
2451c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    // Make sure disconnect() is done once and once only, whether it is called
2461c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    // from the user directly, or called by the destructor.
2471c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    if (mHardware == 0) return res;
2481c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
2491c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    LOG1("hardware teardown");
2501c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    // Before destroying mHardware, we must make sure it's in the
2511c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    // idle state.
2521c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    // Turn off all messages.
253516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    disableMsgType(CAMERA_MSG_ALL_MSGS);
254516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    mHardware->stopPreview();
255516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    mCameraService->updateProxyDeviceState(
256516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        ICameraServiceProxy::CAMERA_STATE_IDLE,
257516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        String8::format("%d", mCameraId));
2581c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    mHardware->cancelPicture();
25965bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    // Release the hardware resources.
26065bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    mHardware->release();
26165bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams
26265bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    // Release the held ANativeWindow resources.
26365bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    if (mPreviewWindow != 0) {
264516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        disconnectWindow(mPreviewWindow);
2651d45c47975ab2a8cef6db5a8976276de31e1e8d0Jason Sams        mPreviewWindow = 0;
266516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        mHardware->setPreviewWindow(mPreviewWindow);
267516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    }
2681c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    mHardware.clear();
2691c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
2701c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    CameraService::Client::disconnect();
2711c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
2721c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    LOG1("disconnect X (pid %d)", callingPid);
2731c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
2741c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    return res;
2751c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams}
2761c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams
27765bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams// ----------------------------------------------------------------------------
27865bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams
2791c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Samsstatus_t CameraClient::setPreviewWindow(const sp<IBinder>& binder,
2801c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams        const sp<ANativeWindow>& window) {
2811c41517124a90fcfdb95dc069fc492c6fcf1ff25Jason Sams    Mutex::Autolock lock(mLock);
282516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    status_t result = checkPidAndHardware();
283516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    if (result != NO_ERROR) return result;
284516c31911578db8ce53529483c3ded918ac7dc6bJason Sams
2852e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    // return if no change in surface.
286516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    if (binder == mSurface) {
287516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        return NO_ERROR;
288516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    }
289516c31911578db8ce53529483c3ded918ac7dc6bJason Sams
290516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    if (window != 0) {
2912e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
292516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        if (result != NO_ERROR) {
293516c31911578db8ce53529483c3ded918ac7dc6bJason Sams            ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
294516c31911578db8ce53529483c3ded918ac7dc6bJason Sams                    result);
295516c31911578db8ce53529483c3ded918ac7dc6bJason Sams            return result;
296516c31911578db8ce53529483c3ded918ac7dc6bJason Sams        }
297516c31911578db8ce53529483c3ded918ac7dc6bJason Sams    }
298718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams
2992e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    // If preview has been already started, register preview buffers now.
300d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (mHardware->previewEnabled()) {
301718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        if (window != 0) {
302718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams            mHardware->setPreviewScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
303d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            mHardware->setPreviewTransform(mOrientation);
304d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            result = mHardware->setPreviewWindow(window);
305718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        }
30670d4e5024298f71edb3b04867e05568f5495b4ceJason Sams    }
307d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
308718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    if (result == NO_ERROR) {
309704ff64b099406bb328898a7443921f22dbffd6dJason Sams        // Everything has succeeded.  Disconnect the old window and remember the
310718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        // new window.
311718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        disconnectWindow(mPreviewWindow);
31270d4e5024298f71edb3b04867e05568f5495b4ceJason Sams        mSurface = binder;
313718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        mPreviewWindow = window;
314718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    } else {
315718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        // Something went wrong after we connected to the new window, so
316718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        // disconnect here.
317718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        disconnectWindow(window);
318718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    }
319718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams
32043ee06857bb7f99446d1d84f8789016c5d105558Jason Sams    return result;
321e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk}
322e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk
3237a22e107d100caea2a661ec73e4525d69f0f9759Jason Sams// set the buffer consumer that the preview will use
324e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchoukstatus_t CameraClient::setPreviewTarget(
325718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        const sp<IGraphicBufferProducer>& bufferProducer) {
326718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
327718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams            getCallingPid());
32843ee06857bb7f99446d1d84f8789016c5d105558Jason Sams
329718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    sp<IBinder> binder;
33070d4e5024298f71edb3b04867e05568f5495b4ceJason Sams    sp<ANativeWindow> window;
331718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    if (bufferProducer != 0) {
332718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        binder = IInterface::asBinder(bufferProducer);
333718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams        // Using controlledByApp flag to ensure that the buffer queue remains in
334d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        // async mode for the old camera API, where many applications depend
335d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        // on that behavior.
336dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        window = new Surface(bufferProducer, /*controlledByApp*/ true);
3372e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    }
338dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    return setPreviewWindow(binder, window);
339dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk}
340dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk
341dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk// set the preview callback flag to affect how the received frames from
342dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk// preview are handled.
343dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchoukvoid CameraClient::setPreviewCallbackFlag(int callback_flag) {
344dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
345dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    Mutex::Autolock lock(mLock);
346581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk    if (checkPidAndHardware() != NO_ERROR) return;
347dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk
348dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    mPreviewCallbackFlag = callback_flag;
349dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
350dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
351dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    } else {
352dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
353dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    }
354dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk}
3552e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams
356dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchoukstatus_t CameraClient::setPreviewCallbackTarget(
357dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        const sp<IGraphicBufferProducer>& callbackProducer) {
358dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    (void)callbackProducer;
359dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    ALOGE("%s: Unimplemented!", __FUNCTION__);
360dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    return INVALID_OPERATION;
361dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk}
362dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk
363581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk// start preview mode
364dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchoukstatus_t CameraClient::startPreview() {
36511c8af9ded3a319635b4e91a639a616ec97fc7e3Jason Sams    LOG1("startPreview (pid %d)", getCallingPid());
366dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    return startCameraMode(CAMERA_PREVIEW_MODE);
367dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk}
368dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk
369dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk// start recording mode
370dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchoukstatus_t CameraClient::startRecording() {
371dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    LOG1("startRecording (pid %d)", getCallingPid());
372dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    return startCameraMode(CAMERA_RECORDING_MODE);
373dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk}
374d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
375d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams// start preview or recording
3763b9c52ab8c1ab240d2299358d01a8efbe392d111Jason Samsstatus_t CameraClient::startCameraMode(camera_mode mode) {
377bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams    LOG1("startCameraMode(%d)", mode);
378bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams    Mutex::Autolock lock(mLock);
379d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    status_t result = checkPidAndHardware();
380bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams    if (result != NO_ERROR) return result;
381bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams
3823b9c52ab8c1ab240d2299358d01a8efbe392d111Jason Sams    switch(mode) {
383c576537166fa3f829e4b5d8c6617a36b47e75fc3Jason Sams        case CAMERA_PREVIEW_MODE:
3843b9c52ab8c1ab240d2299358d01a8efbe392d111Jason Sams            if (mSurface == 0 && mPreviewWindow == 0) {
385d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams                LOG1("mSurface is not set yet.");
386d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams                // still able to start preview in this case.
387dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk            }
3882e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams            return startPreviewMode();
389dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        case CAMERA_RECORDING_MODE:
390dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk            if (mSurface == 0 && mPreviewWindow == 0) {
391dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk                ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
392dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk                return INVALID_OPERATION;
393dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk            }
394dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk            return startRecordingMode();
395dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        default:
396dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk            return UNKNOWN_ERROR;
397dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    }
398581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk}
399dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk
400dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchoukstatus_t CameraClient::startPreviewMode() {
401dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    LOG1("startPreviewMode");
402dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    status_t result = NO_ERROR;
403dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk
404dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    // if preview has been enabled, nothing needs to be done
405d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (mHardware->previewEnabled()) {
406d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return NO_ERROR;
407d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
4085476b450e50939940dcf3f15c92335cee2fc572dJason Sams
409d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (mPreviewWindow != 0) {
410d4b23b54445b13dacaafad97d100999abb36ea6fJason Sams        mHardware->setPreviewScalingMode(
411c576537166fa3f829e4b5d8c6617a36b47e75fc3Jason Sams            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
412d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        mHardware->setPreviewTransform(mOrientation);
413d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
414d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mHardware->setPreviewWindow(mPreviewWindow);
4155476b450e50939940dcf3f15c92335cee2fc572dJason Sams    result = mHardware->startPreview();
4165476b450e50939940dcf3f15c92335cee2fc572dJason Sams    if (result == NO_ERROR) {
4175476b450e50939940dcf3f15c92335cee2fc572dJason Sams        mCameraService->updateProxyDeviceState(
4185476b450e50939940dcf3f15c92335cee2fc572dJason Sams            ICameraServiceProxy::CAMERA_STATE_ACTIVE,
4195476b450e50939940dcf3f15c92335cee2fc572dJason Sams            String8::format("%d", mCameraId));
4205476b450e50939940dcf3f15c92335cee2fc572dJason Sams    }
421f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams    return result;
422f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams}
423f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams
424f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Samsstatus_t CameraClient::startRecordingMode() {
425f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams    LOG1("startRecordingMode");
426f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams    status_t result = NO_ERROR;
427f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams
428fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    // if recording has been enabled, nothing needs to be done
4295476b450e50939940dcf3f15c92335cee2fc572dJason Sams    if (mHardware->recordingEnabled()) {
430fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        return NO_ERROR;
431ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams    }
432ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams
433ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams    // if preview has not been started, start preview first
434fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    if (!mHardware->previewEnabled()) {
4355476b450e50939940dcf3f15c92335cee2fc572dJason Sams        result = startPreviewMode();
4365476b450e50939940dcf3f15c92335cee2fc572dJason Sams        if (result != NO_ERROR) {
437c576537166fa3f829e4b5d8c6617a36b47e75fc3Jason Sams            return result;
43865bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams        }
43965bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    }
4405476b450e50939940dcf3f15c92335cee2fc572dJason Sams
4415476b450e50939940dcf3f15c92335cee2fc572dJason Sams    // start recording mode
442ffe9f48890dde7173a0845d32887fdf94a49b0a7Jason Sams    enableMsgType(CAMERA_MSG_VIDEO_FRAME);
443fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    mCameraService->playSound(CameraService::SOUND_RECORDING_START);
44467f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    result = mHardware->startRecording();
4455476b450e50939940dcf3f15c92335cee2fc572dJason Sams    if (result != NO_ERROR) {
44667f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        ALOGE("mHardware->startRecording() failed with status %d", result);
44767f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    }
44867f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    return result;
44967f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk}
45067f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk
4515476b450e50939940dcf3f15c92335cee2fc572dJason Sams// stop preview mode
4525476b450e50939940dcf3f15c92335cee2fc572dJason Samsvoid CameraClient::stopPreview() {
453c576537166fa3f829e4b5d8c6617a36b47e75fc3Jason Sams    LOG1("stopPreview (pid %d)", getCallingPid());
45465bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    Mutex::Autolock lock(mLock);
45565bdaf1c6d463d9441125d2c87a36015bfef2d95Jason Sams    if (checkPidAndHardware() != NO_ERROR) return;
4565476b450e50939940dcf3f15c92335cee2fc572dJason Sams
4575476b450e50939940dcf3f15c92335cee2fc572dJason Sams
45867f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
45967f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    mHardware->stopPreview();
46026ae3904e8050eae655722caf93ee5d3f0ab195aAlex Sakhartchouk    mCameraService->updateProxyDeviceState(
4614ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams        ICameraServiceProxy::CAMERA_STATE_IDLE,
46226ae3904e8050eae655722caf93ee5d3f0ab195aAlex Sakhartchouk        String8::format("%d", mCameraId));
46326ae3904e8050eae655722caf93ee5d3f0ab195aAlex Sakhartchouk    mPreviewBuffer.clear();
46426ae3904e8050eae655722caf93ee5d3f0ab195aAlex Sakhartchouk}
46526ae3904e8050eae655722caf93ee5d3f0ab195aAlex Sakhartchouk
466f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams// stop recording mode
467f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Samsvoid CameraClient::stopRecording() {
46826ae3904e8050eae655722caf93ee5d3f0ab195aAlex Sakhartchouk    LOG1("stopRecording (pid %d)", getCallingPid());
4694ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    Mutex::Autolock lock(mLock);
4704ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    if (checkPidAndHardware() != NO_ERROR) return;
471f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams
472f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams    disableMsgType(CAMERA_MSG_VIDEO_FRAME);
473f7086090cfc8d97b5bd3b4d7801a27af11f7c207Jason Sams    mHardware->stopRecording();
4744ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    mCameraService->playSound(CameraService::SOUND_RECORDING_STOP);
4758a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
4768a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mPreviewBuffer.clear();
4774ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams}
4784ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams
4798a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams// release a recording frame
4804ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Samsvoid CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
4814ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    Mutex::Autolock lock(mLock);
4824ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    if (checkPidAndHardware() != NO_ERROR) return;
4838a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    if (mem == nullptr) {
4844ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams        android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26164272",
4854ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams                IPCThreadState::self()->getCallingUid(), nullptr, 0);
4864ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams        return;
4874ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    }
4888a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
4898a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mHardware->releaseRecordingFrame(mem);
4904ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams}
491650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
4924ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Samsvoid CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
4934ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    if (handle == nullptr) return;
494650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy
495650a3eb7d621dc8e81573142a4498bbd07bcde27Romain Guy    sp<IMemory> dataPtr;
4964ef6650bd05a39a09958ea1db92f120ea4949cb1Jason Sams    {
497d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        Mutex::Autolock l(mAvailableCallbackBuffersLock);
49849a05d7b82956009f03acbb92a064eed054eb031Jason Sams        if (!mAvailableCallbackBuffers.empty()) {
499d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            dataPtr = mAvailableCallbackBuffers.back();
500d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            mAvailableCallbackBuffers.pop_back();
50149a05d7b82956009f03acbb92a064eed054eb031Jason Sams        }
502d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
50349a05d7b82956009f03acbb92a064eed054eb031Jason Sams
504d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (dataPtr == nullptr) {
505d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        ALOGE("%s: %d: No callback buffer available. Dropping a native handle.", __FUNCTION__,
506d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams                __LINE__);
507d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        native_handle_close(handle);
50849a05d7b82956009f03acbb92a064eed054eb031Jason Sams        native_handle_delete(handle);
509d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return;
510d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
51149a05d7b82956009f03acbb92a064eed054eb031Jason Sams        ALOGE("%s: %d: Callback buffer size doesn't match VideoNativeHandleMetadata", __FUNCTION__,
512768bc02d815a94ad29146f1ed60c847d1af118ccJason Sams                __LINE__);
51349a05d7b82956009f03acbb92a064eed054eb031Jason Sams        native_handle_close(handle);
514768bc02d815a94ad29146f1ed60c847d1af118ccJason Sams        native_handle_delete(handle);
515d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return;
516d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
517d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
51849a05d7b82956009f03acbb92a064eed054eb031Jason Sams    VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
519d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    metadata->eType = kMetadataBufferTypeNativeHandleSource;
520d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    metadata->pHandle = handle;
52149a05d7b82956009f03acbb92a064eed054eb031Jason Sams
522768bc02d815a94ad29146f1ed60c847d1af118ccJason Sams    mHardware->releaseRecordingFrame(dataPtr);
52349a05d7b82956009f03acbb92a064eed054eb031Jason Sams}
524768bc02d815a94ad29146f1ed60c847d1af118ccJason Sams
525d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsstatus_t CameraClient::setVideoBufferMode(int32_t videoBufferMode) {
526d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    LOG1("setVideoBufferMode: %d", videoBufferMode);
527d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    bool enableMetadataInBuffers = false;
52849a05d7b82956009f03acbb92a064eed054eb031Jason Sams
529d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (videoBufferMode == VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA) {
530d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        enableMetadataInBuffers = true;
53149a05d7b82956009f03acbb92a064eed054eb031Jason Sams    } else if (videoBufferMode != VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) {
532d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        ALOGE("%s: %d: videoBufferMode %d is not supported.", __FUNCTION__, __LINE__,
53349a05d7b82956009f03acbb92a064eed054eb031Jason Sams                videoBufferMode);
534d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return BAD_VALUE;
535d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
536d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
537d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Mutex::Autolock lock(mLock);
53849a05d7b82956009f03acbb92a064eed054eb031Jason Sams    if (checkPidAndHardware() != NO_ERROR) {
53949a05d7b82956009f03acbb92a064eed054eb031Jason Sams        return UNKNOWN_ERROR;
54049bdaf0293408159df18a1d8540360f9623c40f7Jason Sams    }
54149bdaf0293408159df18a1d8540360f9623c40f7Jason Sams
54249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    return mHardware->storeMetaDataInBuffers(enableMetadataInBuffers);
54349bdaf0293408159df18a1d8540360f9623c40f7Jason Sams}
54449a05d7b82956009f03acbb92a064eed054eb031Jason Sams
54549bdaf0293408159df18a1d8540360f9623c40f7Jason Samsbool CameraClient::previewEnabled() {
54649bdaf0293408159df18a1d8540360f9623c40f7Jason Sams    LOG1("previewEnabled (pid %d)", getCallingPid());
54749bdaf0293408159df18a1d8540360f9623c40f7Jason Sams
54849bdaf0293408159df18a1d8540360f9623c40f7Jason Sams    Mutex::Autolock lock(mLock);
549fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    if (checkPidAndHardware() != NO_ERROR) return false;
550fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    return mHardware->previewEnabled();
551fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams}
552fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
553fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Samsbool CameraClient::recordingEnabled() {
554fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    LOG1("recordingEnabled (pid %d)", getCallingPid());
555fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
556fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    Mutex::Autolock lock(mLock);
557fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    if (checkPidAndHardware() != NO_ERROR) return false;
558fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    return mHardware->recordingEnabled();
559fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams}
560fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
561fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Samsstatus_t CameraClient::autoFocus() {
562fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    LOG1("autoFocus (pid %d)", getCallingPid());
563fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
564fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    Mutex::Autolock lock(mLock);
565fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    status_t result = checkPidAndHardware();
566fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    if (result != NO_ERROR) return result;
567fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
568fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    return mHardware->autoFocus();
569fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams}
570fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
57149a05d7b82956009f03acbb92a064eed054eb031Jason Samsstatus_t CameraClient::cancelAutoFocus() {
57249a05d7b82956009f03acbb92a064eed054eb031Jason Sams    LOG1("cancelAutoFocus (pid %d)", getCallingPid());
573d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
574d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Mutex::Autolock lock(mLock);
57549a05d7b82956009f03acbb92a064eed054eb031Jason Sams    status_t result = checkPidAndHardware();
576d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (result != NO_ERROR) return result;
57749a05d7b82956009f03acbb92a064eed054eb031Jason Sams
578d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    return mHardware->cancelAutoFocus();
579d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
580d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
581d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams// take a picture - image is returned in callback
58249a05d7b82956009f03acbb92a064eed054eb031Jason Samsstatus_t CameraClient::takePicture(int msgType) {
58349a05d7b82956009f03acbb92a064eed054eb031Jason Sams    LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
584d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
585d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Mutex::Autolock lock(mLock);
58649a05d7b82956009f03acbb92a064eed054eb031Jason Sams    status_t result = checkPidAndHardware();
587d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (result != NO_ERROR) return result;
58849a05d7b82956009f03acbb92a064eed054eb031Jason Sams
589d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
590d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
591d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
59240a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams                " cannot be both enabled");
5932e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        return BAD_VALUE;
59440a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    }
59540a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams
59640a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    // We only accept picture related message types
59740a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    // and ignore other types of messages for takePicture().
598e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    int picMsgType = msgType
599e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk                        & (CAMERA_MSG_SHUTTER |
600ae209acd8d48755df7d49459b1bcbc3b8e20561dJoe Onorato                           CAMERA_MSG_POSTVIEW_FRAME |
60140a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams                           CAMERA_MSG_RAW_IMAGE |
60240a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams                           CAMERA_MSG_RAW_IMAGE_NOTIFY |
60340a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams                           CAMERA_MSG_COMPRESSED_IMAGE);
604fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
605fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    enableMsgType(picMsgType);
606fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
607fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    return mHardware->takePicture();
608fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams}
609e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk
610e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk// set preview/capture parameters - key/value pairs
611fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Samsstatus_t CameraClient::setParameters(const String8& params) {
612fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
613fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
614fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    Mutex::Autolock lock(mLock);
615fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    status_t result = checkPidAndHardware();
616fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    if (result != NO_ERROR) return result;
617fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
618fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    mLatestSetParameters = CameraParameters(params);
619fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    CameraParameters p(params);
620e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    return mHardware->setParameters(p);
621e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk}
622fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams
623fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams// get preview/capture parameters - key/value pairs
624fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason SamsString8 CameraClient::getParameters() const {
625fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210Jason Sams    Mutex::Autolock lock(mLock);
6262e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    // The camera service can unconditionally get the parameters at all times
62740a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    if (getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) return String8();
62840a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams
629a8f2acee39aae94f9d7148f775ca8e35344da4b4Joe Onorato    String8 params(mHardware->getParameters().flatten());
63040a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
631e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    return params;
632e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk}
633ae209acd8d48755df7d49459b1bcbc3b8e20561dJoe Onorato
63440a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams// enable shutter sound
635d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsstatus_t CameraClient::enableShutterSound(bool enable) {
636dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    LOG1("enableShutterSound (pid %d)", getCallingPid());
6372e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams
638dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    status_t result = checkPidAndHardware();
639dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    if (result != NO_ERROR) return result;
640581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk
641dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk    if (enable) {
642dfac814c18f73dd7289f9927edca3e3b6ec6bc00Alex Sakhartchouk        mPlayShutterSound = true;
6435edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams        return OK;
6445edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    }
6455edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams
6465edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    // the camera2 api legacy mode can unconditionally disable the shutter sound
6475edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    if (mLegacyMode) {
6485edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams        ALOGV("%s: Disable shutter sound in legacy mode", __FUNCTION__);
6495edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams        mPlayShutterSound = false;
6505edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams        return OK;
6515edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    }
6525edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams
6535edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    // Disabling shutter sound may not be allowed. In that case only
6545edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    // allow the mediaserver process to disable the sound.
6555edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    char value[PROPERTY_VALUE_MAX];
6565edc608a0749ed4b7074b5c1243043eb722c3c31Jason Sams    property_get("ro.camera.sound.forced", value, "0");
657aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    if (strcmp(value, "0") != 0) {
658aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        // Disabling shutter sound is not allowed. Deny if the current
659aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        // process is not mediaserver.
6602e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        if (getCallingPid() != getpid()) {
661aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
662aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk            return PERMISSION_DENIED;
663aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        }
664aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
665aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
666b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    mPlayShutterSound = false;
667b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    return OK;
668b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk}
669b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
670b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchoukstatus_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
671b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    LOG1("sendCommand (pid %d)", getCallingPid());
672b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    int orientation;
673b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    Mutex::Autolock lock(mLock);
674b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    status_t result = checkPidAndHardware();
675b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    if (result != NO_ERROR) return result;
676b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
677b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
678b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        // Mirror the preview if the camera is front-facing.
679b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
680b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        if (orientation == -1) return BAD_VALUE;
681b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
682b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        if (mOrientation != orientation) {
683b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            mOrientation = orientation;
684b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            if (mPreviewWindow != 0) {
685b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk                mHardware->setPreviewTransform(mOrientation);
686b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            }
687b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        }
688b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        return OK;
689b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
690b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        switch (arg1) {
691b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            case 0:
692b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk                return enableShutterSound(false);
693b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            case 1:
694aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk                return enableShutterSound(true);
695aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk            default:
696aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk                return BAD_VALUE;
697aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        }
6982e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        return OK;
699aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
700aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        mCameraService->playSound(CameraService::SOUND_RECORDING_START);
701581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk    } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
702aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        // Silently ignore this command
703aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        return INVALID_OPERATION;
704aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    } else if (cmd == CAMERA_CMD_PING) {
705aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk        // If mHardware is 0, checkPidAndHardware will return error.
7062e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        return OK;
707aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    }
708aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
709aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    return mHardware->sendCommand(cmd, arg1, arg2);
710aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk}
711581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchouk
712aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk// ----------------------------------------------------------------------------
713aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
714aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukvoid CameraClient::enableMsgType(int32_t msgType) {
715aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    android_atomic_or(msgType, &mMsgEnabled);
716aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    mHardware->enableMsgType(msgType);
717aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk}
718aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
719aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchoukvoid CameraClient::disableMsgType(int32_t msgType) {
720aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    android_atomic_and(~msgType, &mMsgEnabled);
721aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    mHardware->disableMsgType(msgType);
7222e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams}
723aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk
724aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk#define CHECK_MESSAGE_INTERVAL 10 // 10ms
725581cc64028e8b8f66cec8105bf530b16d5fb34ebAlex Sakhartchoukbool CameraClient::lockIfMessageWanted(int32_t msgType) {
726aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    int sleepCount = 0;
727aae74ad6144470c66e72b075ac3afeddb186fa98Alex Sakhartchouk    while (mMsgEnabled & msgType) {
728d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        if (mLock.tryLock() == NO_ERROR) {
729d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            if (sleepCount > 0) {
730d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams                LOG1("lockIfMessageWanted(%d): waited for %d ms",
7319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk                    msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
732b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            }
733b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
7349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk            // If messages are no longer enabled after acquiring lock, release and drop message
735b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            if ((mMsgEnabled & msgType) == 0) {
736e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk                mLock.unlock();
737e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk                break;
738e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk            }
739b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
740b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            return true;
741b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        }
742b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        if (sleepCount++ == 0) {
743b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk            LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
744b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        }
745b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        usleep(CHECK_MESSAGE_INTERVAL * 1000);
746b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    }
747b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
748b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    return false;
749b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk}
750e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk
751e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk// Callback messages can be dispatched to internal handlers or pass to our
752e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk// client's callback functions, depending on the message type.
753b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//
754b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk// notifyCallback:
755b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      CAMERA_MSG_SHUTTER              handleShutter
756b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      (others)                        c->notifyCallback
757b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk// dataCallback:
758b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
759b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
760b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      CAMERA_MSG_RAW_IMAGE            handleRawPicture
761b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
762b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      (others)                        c->dataCallback
763b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk// dataCallbackTimestamp
764b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk//      (others)                        c->dataCallbackTimestamp
765b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
766b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchoukvoid CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
767b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        int32_t ext2, void* user) {
768b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    LOG2("notifyCallback(%d)", msgType);
769b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk
770b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    sp<CameraClient> client = static_cast<CameraClient*>(getClientFromCookie(user).get());
7719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk    if (client.get() == nullptr) return;
772e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk
773e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    if (!client->lockIfMessageWanted(msgType)) return;
774e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk
775b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    switch (msgType) {
776b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        case CAMERA_MSG_SHUTTER:
7779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk            // ext1 is the dimension of the yuv picture.
7789b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk            client->handleShutter();
7799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk            break;
780bd1c3ad0cdf8e60b849a009cdc0b36764cc1dacbJason Sams        default:
781bd1c3ad0cdf8e60b849a009cdc0b36764cc1dacbJason Sams            client->handleGenericNotify(msgType, ext1, ext2);
782bd1c3ad0cdf8e60b849a009cdc0b36764cc1dacbJason Sams            break;
7832e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    }
784d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
785d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
786bc948dedcee57a66fe2cb38d4c79d04a10c7efb3Jason Samsvoid CameraClient::dataCallback(int32_t msgType,
787d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
788d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    LOG2("dataCallback(%d)", msgType);
789d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
7902e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    sp<CameraClient> client = static_cast<CameraClient*>(getClientFromCookie(user).get());
7914d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    if (client.get() == nullptr) return;
792cfc04366998cd0c626594c9cf70336a11bdf5996Jason Sams
7934d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    if (!client->lockIfMessageWanted(msgType)) return;
7944d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    if (dataPtr == 0 && metadata == NULL) {
7954d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        ALOGE("Null data returned in data callback");
7964d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
7976f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams        return;
7986f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams    }
7996f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams
8006f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
8016f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams        case CAMERA_MSG_PREVIEW_FRAME:
8026f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams            client->handlePreviewData(msgType, dataPtr, metadata);
8036f4cf0b8885403ead157ae00fd43cf1282331c23Jason Sams            break;
804031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines        case CAMERA_MSG_POSTVIEW_FRAME:
805031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines            client->handlePostview(dataPtr);
806031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines            break;
807031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines        case CAMERA_MSG_RAW_IMAGE:
808031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines            client->handleRawPicture(dataPtr);
809031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines            break;
810031ec58cfc7a20927302a5300eba3f5fc1709b50Stephen Hines        case CAMERA_MSG_COMPRESSED_IMAGE:
8112e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams            client->handleCompressedPicture(dataPtr);
8124d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams            break;
813ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines        default:
8144d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams            client->handleGenericData(msgType, dataPtr, metadata);
8154d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams            break;
8164d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    }
8174d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams}
818ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines
819ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hinesvoid CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
820ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines        int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
821ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines    LOG2("dataCallbackTimestamp(%d)", msgType);
822ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines
823ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines    sp<CameraClient> client = static_cast<CameraClient*>(getClientFromCookie(user).get());
824ca54ec302f5bddd1674ea1f36cd3b7c540b2fbcaStephen Hines    if (client.get() == nullptr) return;
8252e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams
8264d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    if (!client->lockIfMessageWanted(msgType)) return;
8274d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams
8284d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    if (dataPtr == 0) {
8294d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        ALOGE("Null data returned in data with timestamp callback");
8304d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
8314d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        return;
8324d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    }
8334d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams
834d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
835d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
8362e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams
837584a375df68ed7d62b38389078c6804edf228f9cRomain Guy// snapshot taken callback
83807ae40623737a6060b8a925fd2e6bba76780dcd4Jason Samsvoid CameraClient::handleShutter(void) {
839584a375df68ed7d62b38389078c6804edf228f9cRomain Guy    if (mPlayShutterSound) {
840584a375df68ed7d62b38389078c6804edf228f9cRomain Guy        mCameraService->playSound(CameraService::SOUND_SHUTTER);
841584a375df68ed7d62b38389078c6804edf228f9cRomain Guy    }
842584a375df68ed7d62b38389078c6804edf228f9cRomain Guy
843584a375df68ed7d62b38389078c6804edf228f9cRomain Guy    sp<hardware::ICameraClient> c = mRemoteCallback;
844bc948dedcee57a66fe2cb38d4c79d04a10c7efb3Jason Sams    if (c != 0) {
845584a375df68ed7d62b38389078c6804edf228f9cRomain Guy        mLock.unlock();
846584a375df68ed7d62b38389078c6804edf228f9cRomain Guy        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
847584a375df68ed7d62b38389078c6804edf228f9cRomain Guy        if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
848584a375df68ed7d62b38389078c6804edf228f9cRomain Guy    }
849584a375df68ed7d62b38389078c6804edf228f9cRomain Guy    disableMsgType(CAMERA_MSG_SHUTTER);
850584a375df68ed7d62b38389078c6804edf228f9cRomain Guy
85122534176fb5c1257130ef4ee589739ca42766a32Jason Sams    // Shutters only happen in response to takePicture, so mark device as
8522e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    // idle now, until preview is restarted
85322534176fb5c1257130ef4ee589739ca42766a32Jason Sams    mCameraService->updateProxyDeviceState(
8544d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        ICameraServiceProxy::CAMERA_STATE_IDLE,
8554d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams        String8::format("%d", mCameraId));
85622534176fb5c1257130ef4ee589739ca42766a32Jason Sams
85722534176fb5c1257130ef4ee589739ca42766a32Jason Sams    mLock.unlock();
858584a375df68ed7d62b38389078c6804edf228f9cRomain Guy}
8592e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams
860be2e84193f709419634de4cc3ba0e67acf6976f3Jason Sams// preview callback - frame buffer update
8614d3399337d18ef04116bc8a2e5799274655d0c30Jason Samsvoid CameraClient::handlePreviewData(int32_t msgType,
8624d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams                                              const sp<IMemory>& mem,
8634d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams                                              camera_frame_metadata_t *metadata) {
8644d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    ssize_t offset;
8654d3399337d18ef04116bc8a2e5799274655d0c30Jason Sams    size_t size;
866be2e84193f709419634de4cc3ba0e67acf6976f3Jason Sams    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
867be2e84193f709419634de4cc3ba0e67acf6976f3Jason Sams
8686e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    // local copy of the callback flags
8696e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    int flags = mPreviewCallbackFlag;
8706e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams
8716e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    // is callback enabled?
8726e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
8736e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams        // If the enable bit is off, the copy-out and one-shot bits are ignored
8746e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams        LOG2("frame callback is disabled");
8756e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams        mLock.unlock();
8766e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams        return;
8776e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    }
8786e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams
8796e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    // hold a strong pointer to the client
8806e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    sp<hardware::ICameraClient> c = mRemoteCallback;
8816e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams
8826e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    // clear callback flags if no client or one-shot mode
8836e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams    if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
8846e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams        LOG2("Disable preview callback");
8856e494d3ab606be8c06f8d4930fbec572bbfa15c2Jason Sams        mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
886d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams                                  CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
887fbf0b9ecda03fbdbd4ebabfd18da09a789686249Jason Sams                                  CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
888fbf0b9ecda03fbdbd4ebabfd18da09a789686249Jason Sams        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
889e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    }
890e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
891e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    if (c != 0) {
892e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        // Is the received frame copied out or not?
893d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
894e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams            LOG2("frame is copied");
895e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
896e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        } else {
897e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams            LOG2("frame is forwarded");
898e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams            mLock.unlock();
8998451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            c->dataCallback(msgType, mem, metadata);
90043702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich        }
90143702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    } else {
90243702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich        mLock.unlock();
90343702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    }
9048451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes}
90543702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich
90643702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich// picture callback - postview image ready
90743702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevichvoid CameraClient::handlePostview(const sp<IMemory>& mem) {
90843702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
9098451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
91043702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    sp<hardware::ICameraClient> c = mRemoteCallback;
91143702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    mLock.unlock();
912e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    if (c != 0) {
91343702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
91443702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    }
9158451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes}
9168451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
91743702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich// picture callback - raw image ready
91843702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevichvoid CameraClient::handleRawPicture(const sp<IMemory>& mem) {
919e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    disableMsgType(CAMERA_MSG_RAW_IMAGE);
92043702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich
92143702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    ssize_t offset;
922e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    size_t size;
923e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
924e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk
925e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    sp<hardware::ICameraClient> c = mRemoteCallback;
926e7c4a7565c7f8c8fc1ec92dc0692577fcc474750Alex Sakhartchouk    mLock.unlock();
927e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    if (c != 0) {
92839ddc950c9064129ead5de04b200106c0659f937Jason Sams        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
92943702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich    }
930e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams}
931e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
93243702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevich// picture callback - compressed picture ready
93343702d8925c54360ad5f9f66b0d35d61d59f6910Jack Palevichvoid CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
934d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
935e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
936d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    sp<hardware::ICameraClient> c = mRemoteCallback;
937d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mLock.unlock();
938d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (c != 0) {
939d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
940d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
941331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams}
942331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams
943331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams
944331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Samsvoid CameraClient::handleGenericNotify(int32_t msgType,
945331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    int32_t ext1, int32_t ext2) {
946d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    sp<hardware::ICameraClient> c = mRemoteCallback;
94754db59c3594e887a412a24713fc3daa1c2404593Jason Sams    mLock.unlock();
948331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    if (c != 0) {
949331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams        c->notifyCallback(msgType, ext1, ext2);
950331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    }
951d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
952d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
9530011bcf57ff711a221a3a4c73f2a79125111647dJason Samsvoid CameraClient::handleGenericData(int32_t msgType,
9540011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
9550011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    sp<hardware::ICameraClient> c = mRemoteCallback;
9562e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    mLock.unlock();
9570011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    if (c != 0) {
9580011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        c->dataCallback(msgType, dataPtr, metadata);
9590011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
9600011bcf57ff711a221a3a4c73f2a79125111647dJason Sams}
96154c0ec14e016e4a1bf3ceab40ed6ca5447da4725Jason Sams
962d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
9632e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    int32_t msgType, const sp<IMemory>& dataPtr) {
96454c0ec14e016e4a1bf3ceab40ed6ca5447da4725Jason Sams    sp<hardware::ICameraClient> c = mRemoteCallback;
96568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    mLock.unlock();
96668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    if (c != 0 && dataPtr != nullptr) {
96754c0ec14e016e4a1bf3ceab40ed6ca5447da4725Jason Sams        native_handle_t* handle = nullptr;
96854c0ec14e016e4a1bf3ceab40ed6ca5447da4725Jason Sams
96954c0ec14e016e4a1bf3ceab40ed6ca5447da4725Jason Sams        // Check if dataPtr contains a VideoNativeHandleMetadata.
9702e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) {
971d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            VideoNativeHandleMetadata *metadata =
97268afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                (VideoNativeHandleMetadata*)(dataPtr->pointer());
97368afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
974d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams                handle = metadata->pHandle;
975d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            }
97668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        }
977d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
97868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        // If dataPtr contains a native handle, send it via recordingFrameHandleCallbackTimestamp.
979b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk        if (handle != nullptr) {
9807e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            {
981b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk                Mutex::Autolock l(mAvailableCallbackBuffersLock);
9827e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                mAvailableCallbackBuffers.push_back(dataPtr);
9837e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            }
9847e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            c->recordingFrameHandleCallbackTimestamp(timestamp, handle);
985991040c8261237997915f8a4c899a6ea5012fb42Jason Sams        } else {
9867e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
987b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        }
9887e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    }
9897e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams}
9907e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams
9917e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Samsvoid CameraClient::copyFrameAndPostCopiedFrame(
9927e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        int32_t msgType, const sp<hardware::ICameraClient>& client,
9931fe9b8c3bdc55e624edc1a69c3f3f0b9e90af1e4Jason Sams        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
9941fe9b8c3bdc55e624edc1a69c3f3f0b9e90af1e4Jason Sams        camera_frame_metadata_t *metadata) {
9950011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    LOG2("copyFrameAndPostCopiedFrame");
996b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk    // It is necessary to copy out of pmem before sending this to
9971fe9b8c3bdc55e624edc1a69c3f3f0b9e90af1e4Jason Sams    // the callback. For efficiency, reuse the same MemoryHeapBase
998b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk    // provided it's big enough. Don't allocate the memory or
9990011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    // perform the copy if there's no callback.
10000011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    // hold the preview lock while we grab a reference to the preview buffer
10011fe9b8c3bdc55e624edc1a69c3f3f0b9e90af1e4Jason Sams    sp<MemoryHeapBase> previewBuffer;
1002991040c8261237997915f8a4c899a6ea5012fb42Jason Sams
1003ee41112e1539de95596600fd2c6dada5d275217fJason Sams    if (mPreviewBuffer == 0) {
1004b0253ea6969bdd27bf574e0da7fa91aa6d09f44fAlex Sakhartchouk        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
10050011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    } else if (size > mPreviewBuffer->virtualSize()) {
10060011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        mPreviewBuffer.clear();
10071fe9b8c3bdc55e624edc1a69c3f3f0b9e90af1e4Jason Sams        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
10081fe9b8c3bdc55e624edc1a69c3f3f0b9e90af1e4Jason Sams    }
1009ebfb436a49673693b98469683451bd9ede797557Jason Sams    if (mPreviewBuffer == 0) {
1010ebfb436a49673693b98469683451bd9ede797557Jason Sams        ALOGE("failed to allocate space for preview buffer");
1011ebfb436a49673693b98469683451bd9ede797557Jason Sams        mLock.unlock();
1012331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams        return;
1013331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    }
1014ebfb436a49673693b98469683451bd9ede797557Jason Sams    previewBuffer = mPreviewBuffer;
101580a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk
101680a4c2cd34aedb4f1a2e5e7d1ac26a9aeebe41aeAlex Sakhartchouk    void* previewBufferBase = previewBuffer->base();
1017331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    void* heapBase = heap->base();
1018ebfb436a49673693b98469683451bd9ede797557Jason Sams
1019ebfb436a49673693b98469683451bd9ede797557Jason Sams    if (heapBase == MAP_FAILED) {
1020d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        ALOGE("%s: Failed to mmap heap for preview frame.", __FUNCTION__);
1021d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        mLock.unlock();
1022d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return;
1023d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    } else if (previewBufferBase == MAP_FAILED) {
10242e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        ALOGE("%s: Failed to mmap preview buffer for preview frame.", __FUNCTION__);
1025d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        mLock.unlock();
1026d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return;
1027bc948dedcee57a66fe2cb38d4c79d04a10c7efb3Jason Sams    }
1028d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
1029d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    memcpy(previewBufferBase, (uint8_t *) heapBase + offset, size);
1030d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
10312e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
1032d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (frame == 0) {
103354db59c3594e887a412a24713fc3daa1c2404593Jason Sams        ALOGE("failed to allocate space for frame callback");
103454db59c3594e887a412a24713fc3daa1c2404593Jason Sams        mLock.unlock();
1035d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        return;
1036d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
1037d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
10382e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams    mLock.unlock();
1039d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    client->dataCallback(msgType, frame, metadata);
1040d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
1041bc948dedcee57a66fe2cb38d4c79d04a10c7efb3Jason Sams
1042d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsint CameraClient::getOrientation(int degrees, bool mirror) {
1043d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (!mirror) {
10440826a6f90f049bf94fc39fb23ad3a736a14b96ebJason Sams        if (degrees == 0) return 0;
10452e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
10460826a6f90f049bf94fc39fb23ad3a736a14b96ebJason Sams        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
10470826a6f90f049bf94fc39fb23ad3a736a14b96ebJason Sams        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
1048bc948dedcee57a66fe2cb38d4c79d04a10c7efb3Jason Sams    } else {  // Do mirror (horizontal flip)
10490826a6f90f049bf94fc39fb23ad3a736a14b96ebJason Sams        if (degrees == 0) {           // FLIP_H and ROT_0
10500826a6f90f049bf94fc39fb23ad3a736a14b96ebJason Sams            return HAL_TRANSFORM_FLIP_H;
1051d7b3774da62d3c70cc7e8cf549967a1c823501e6Joe Onorato        } else if (degrees == 90) {   // FLIP_H and ROT_90
10522e1872fe07cf8952812a417985e6e1f61bdeab5dJason Sams            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
1053ebfb436a49673693b98469683451bd9ede797557Jason Sams        } else if (degrees == 180) {  // FLIP_H and ROT_180
1054ebfb436a49673693b98469683451bd9ede797557Jason Sams            return HAL_TRANSFORM_FLIP_V;
1055ebfb436a49673693b98469683451bd9ede797557Jason Sams        } else if (degrees == 270) {  // FLIP_H and ROT_270
1056ebfb436a49673693b98469683451bd9ede797557Jason Sams            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1057ebfb436a49673693b98469683451bd9ede797557Jason Sams        }
1058d7b3774da62d3c70cc7e8cf549967a1c823501e6Joe Onorato    }
105902fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams    ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
106002fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams    return -1;
106102fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams}
1062a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchouk
1063a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchoukstatus_t CameraClient::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) {
106402fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams    (void)bufferProducer;
1065bba134c8a1dcfe0c8473307a95899a02c9553504Jason Sams    ALOGE("%s: %d: CameraClient doesn't support setting a video target.", __FUNCTION__, __LINE__);
1066a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchouk    return INVALID_OPERATION;
1067a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchouk}
1068a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchouk
1069a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchouk}; // namespace android
1070a89094aa3bc059c6e03b20b4c5b1ede4582f3da9Alex Sakhartchouk