summaryrefslogtreecommitdiffstats
path: root/camera/ICameraService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/ICameraService.cpp')
-rw-r--r--camera/ICameraService.cpp220
1 files changed, 202 insertions, 18 deletions
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index 134f7f0..5fc89fb 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -15,6 +15,9 @@
** limitations under the License.
*/
+#define LOG_TAG "BpCameraService"
+#include <utils/Log.h>
+
#include <stdint.h>
#include <sys/types.h>
@@ -28,9 +31,59 @@
#include <camera/IProCameraCallbacks.h>
#include <camera/ICamera.h>
#include <camera/ICameraClient.h>
+#include <camera/camera2/ICameraDeviceUser.h>
+#include <camera/camera2/ICameraDeviceCallbacks.h>
+#include <camera/CameraMetadata.h>
namespace android {
+namespace {
+
+enum {
+ EX_SECURITY = -1,
+ EX_BAD_PARCELABLE = -2,
+ EX_ILLEGAL_ARGUMENT = -3,
+ EX_NULL_POINTER = -4,
+ EX_ILLEGAL_STATE = -5,
+ EX_HAS_REPLY_HEADER = -128, // special; see below
+};
+
+static bool readExceptionCode(Parcel& reply) {
+ int32_t exceptionCode = reply.readExceptionCode();
+
+ if (exceptionCode != 0) {
+ const char* errorMsg;
+ switch(exceptionCode) {
+ case EX_SECURITY:
+ errorMsg = "Security";
+ break;
+ case EX_BAD_PARCELABLE:
+ errorMsg = "BadParcelable";
+ break;
+ case EX_NULL_POINTER:
+ errorMsg = "NullPointer";
+ break;
+ case EX_ILLEGAL_STATE:
+ errorMsg = "IllegalState";
+ break;
+ // Binder should be handling this code inside Parcel::readException
+ // but lets have a to-string here anyway just in case.
+ case EX_HAS_REPLY_HEADER:
+ errorMsg = "HasReplyHeader";
+ break;
+ default:
+ errorMsg = "Unknown";
+ }
+
+ ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
+ return true;
+ }
+
+ return false;
+}
+
+};
+
class BpCameraService: public BpInterface<ICameraService>
{
public:
@@ -45,6 +98,8 @@ public:
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
+
+ if (readExceptionCode(reply)) return 0;
return reply.readInt32();
}
@@ -55,14 +110,44 @@ public:
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeInt32(cameraId);
remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
- cameraInfo->facing = reply.readInt32();
- cameraInfo->orientation = reply.readInt32();
- return reply.readInt32();
+
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t result = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ cameraInfo->facing = reply.readInt32();
+ cameraInfo->orientation = reply.readInt32();
+ }
+ return result;
+ }
+
+ // get camera characteristics (static metadata)
+ virtual status_t getCameraCharacteristics(int cameraId,
+ CameraMetadata* cameraInfo) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
+ data.writeInt32(cameraId);
+ remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
+
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t result = reply.readInt32();
+
+ CameraMetadata out;
+ if (reply.readInt32() != 0) {
+ out.readFromParcel(&reply);
+ }
+
+ if (cameraInfo != NULL) {
+ cameraInfo->swap(out);
+ }
+
+ return result;
}
- // connect to camera service
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId,
- const String16 &clientPackageName, int clientUid)
+ // connect to camera service (android.hardware.Camera)
+ virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
+ const String16 &clientPackageName, int clientUid,
+ /*out*/
+ sp<ICamera>& device)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
@@ -71,12 +156,20 @@ public:
data.writeString16(clientPackageName);
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT, data, &reply);
- return interface_cast<ICamera>(reply.readStrongBinder());
+
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<ICamera>(reply.readStrongBinder());
+ }
+ return status;
}
// connect to camera service (pro client)
- virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
- const String16 &clientPackageName, int clientUid)
+ virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
+ const String16 &clientPackageName, int clientUid,
+ /*out*/
+ sp<IProCameraUser>& device)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
@@ -85,7 +178,38 @@ public:
data.writeString16(clientPackageName);
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
- return interface_cast<IProCameraUser>(reply.readStrongBinder());
+
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<IProCameraUser>(reply.readStrongBinder());
+ }
+ return status;
+ }
+
+ // connect to camera service (android.hardware.camera2.CameraDevice)
+ virtual status_t connectDevice(
+ const sp<ICameraDeviceCallbacks>& cameraCb,
+ int cameraId,
+ const String16& clientPackageName,
+ int clientUid,
+ /*out*/
+ sp<ICameraDeviceUser>& device)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
+ data.writeStrongBinder(cameraCb->asBinder());
+ data.writeInt32(cameraId);
+ data.writeString16(clientPackageName);
+ data.writeInt32(clientUid);
+ remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
+
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
+ }
+ return status;
}
virtual status_t addListener(const sp<ICameraServiceListener>& listener)
@@ -94,6 +218,8 @@ public:
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(listener->asBinder());
remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
+
+ if (readExceptionCode(reply)) return -EPROTO;
return reply.readInt32();
}
@@ -103,6 +229,8 @@ public:
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(listener->asBinder());
remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
+
+ if (readExceptionCode(reply)) return -EPROTO;
return reply.readInt32();
}
};
@@ -117,17 +245,34 @@ status_t BnCameraService::onTransact(
switch(code) {
case GET_NUMBER_OF_CAMERAS: {
CHECK_INTERFACE(ICameraService, data, reply);
+ reply->writeNoException();
reply->writeInt32(getNumberOfCameras());
return NO_ERROR;
} break;
case GET_CAMERA_INFO: {
CHECK_INTERFACE(ICameraService, data, reply);
- CameraInfo cameraInfo;
+ CameraInfo cameraInfo = CameraInfo();
memset(&cameraInfo, 0, sizeof(cameraInfo));
status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
+ reply->writeNoException();
+ reply->writeInt32(result);
+
+ // Fake a parcelable object here
+ reply->writeInt32(1); // means the parcelable is included
reply->writeInt32(cameraInfo.facing);
reply->writeInt32(cameraInfo.orientation);
+ return NO_ERROR;
+ } break;
+ case GET_CAMERA_CHARACTERISTICS: {
+ CHECK_INTERFACE(ICameraService, data, reply);
+ CameraMetadata info;
+ status_t result = getCameraCharacteristics(data.readInt32(), &info);
+ reply->writeNoException();
reply->writeInt32(result);
+
+ // out-variables are after exception and return value
+ reply->writeInt32(1); // means the parcelable is included
+ info.writeToParcel(reply);
return NO_ERROR;
} break;
case CONNECT: {
@@ -137,26 +282,64 @@ status_t BnCameraService::onTransact(
int32_t cameraId = data.readInt32();
const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
- sp<ICamera> camera = connect(cameraClient, cameraId,
- clientName, clientUid);
- reply->writeStrongBinder(camera->asBinder());
+ sp<ICamera> camera;
+ status_t status = connect(cameraClient, cameraId,
+ clientName, clientUid, /*out*/ camera);
+ reply->writeNoException();
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
return NO_ERROR;
} break;
case CONNECT_PRO: {
CHECK_INTERFACE(ICameraService, data, reply);
- sp<IProCameraCallbacks> cameraClient = interface_cast<IProCameraCallbacks>(data.readStrongBinder());
+ sp<IProCameraCallbacks> cameraClient =
+ interface_cast<IProCameraCallbacks>(data.readStrongBinder());
+ int32_t cameraId = data.readInt32();
+ const String16 clientName = data.readString16();
+ int32_t clientUid = data.readInt32();
+ sp<IProCameraUser> camera;
+ status_t status = connectPro(cameraClient, cameraId,
+ clientName, clientUid, /*out*/ camera);
+ reply->writeNoException();
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
+ return NO_ERROR;
+ } break;
+ case CONNECT_DEVICE: {
+ CHECK_INTERFACE(ICameraService, data, reply);
+ sp<ICameraDeviceCallbacks> cameraClient =
+ interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
int32_t cameraId = data.readInt32();
const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
- sp<IProCameraUser> camera = connect(cameraClient, cameraId,
- clientName, clientUid);
- reply->writeStrongBinder(camera->asBinder());
+ sp<ICameraDeviceUser> camera;
+ status_t status = connectDevice(cameraClient, cameraId,
+ clientName, clientUid, /*out*/ camera);
+ reply->writeNoException();
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
return NO_ERROR;
} break;
case ADD_LISTENER: {
CHECK_INTERFACE(ICameraService, data, reply);
sp<ICameraServiceListener> listener =
interface_cast<ICameraServiceListener>(data.readStrongBinder());
+ reply->writeNoException();
reply->writeInt32(addListener(listener));
return NO_ERROR;
} break;
@@ -164,6 +347,7 @@ status_t BnCameraService::onTransact(
CHECK_INTERFACE(ICameraService, data, reply);
sp<ICameraServiceListener> listener =
interface_cast<ICameraServiceListener>(data.readStrongBinder());
+ reply->writeNoException();
reply->writeInt32(removeListener(listener));
return NO_ERROR;
} break;