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