1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2008, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ICameraClient"
20*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <stdint.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <sys/types.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <camera/CameraUtils.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/ICameraClient.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <media/hardware/HardwareAPI.h>
26*ec779b8eSAndroid Build Coastguard Worker
27*ec779b8eSAndroid Build Coastguard Worker namespace android {
28*ec779b8eSAndroid Build Coastguard Worker namespace hardware {
29*ec779b8eSAndroid Build Coastguard Worker
30*ec779b8eSAndroid Build Coastguard Worker enum {
31*ec779b8eSAndroid Build Coastguard Worker NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
32*ec779b8eSAndroid Build Coastguard Worker DATA_CALLBACK,
33*ec779b8eSAndroid Build Coastguard Worker DATA_CALLBACK_TIMESTAMP,
34*ec779b8eSAndroid Build Coastguard Worker RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP,
35*ec779b8eSAndroid Build Coastguard Worker RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH,
36*ec779b8eSAndroid Build Coastguard Worker };
37*ec779b8eSAndroid Build Coastguard Worker
38*ec779b8eSAndroid Build Coastguard Worker class BpCameraClient: public BpInterface<ICameraClient>
39*ec779b8eSAndroid Build Coastguard Worker {
40*ec779b8eSAndroid Build Coastguard Worker public:
BpCameraClient(const sp<IBinder> & impl)41*ec779b8eSAndroid Build Coastguard Worker explicit BpCameraClient(const sp<IBinder>& impl)
42*ec779b8eSAndroid Build Coastguard Worker : BpInterface<ICameraClient>(impl)
43*ec779b8eSAndroid Build Coastguard Worker {
44*ec779b8eSAndroid Build Coastguard Worker }
45*ec779b8eSAndroid Build Coastguard Worker
46*ec779b8eSAndroid Build Coastguard Worker // generic callback from camera service to app
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)47*ec779b8eSAndroid Build Coastguard Worker void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
48*ec779b8eSAndroid Build Coastguard Worker {
49*ec779b8eSAndroid Build Coastguard Worker ALOGV("notifyCallback");
50*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply;
51*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
52*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(msgType);
53*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(ext1);
54*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(ext2);
55*ec779b8eSAndroid Build Coastguard Worker remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
56*ec779b8eSAndroid Build Coastguard Worker }
57*ec779b8eSAndroid Build Coastguard Worker
58*ec779b8eSAndroid Build Coastguard Worker // generic data callback from camera service to app with image data
dataCallback(int32_t msgType,const sp<IMemory> & imageData,camera_frame_metadata_t * metadata)59*ec779b8eSAndroid Build Coastguard Worker void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
60*ec779b8eSAndroid Build Coastguard Worker camera_frame_metadata_t *metadata)
61*ec779b8eSAndroid Build Coastguard Worker {
62*ec779b8eSAndroid Build Coastguard Worker ALOGV("dataCallback");
63*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply;
64*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
65*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(msgType);
66*ec779b8eSAndroid Build Coastguard Worker data.writeStrongBinder(IInterface::asBinder(imageData));
67*ec779b8eSAndroid Build Coastguard Worker if (metadata) {
68*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(metadata->number_of_faces);
69*ec779b8eSAndroid Build Coastguard Worker data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces);
70*ec779b8eSAndroid Build Coastguard Worker }
71*ec779b8eSAndroid Build Coastguard Worker remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
72*ec779b8eSAndroid Build Coastguard Worker }
73*ec779b8eSAndroid Build Coastguard Worker
74*ec779b8eSAndroid Build Coastguard Worker // generic data callback from camera service to app with image data
dataCallbackTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & imageData)75*ec779b8eSAndroid Build Coastguard Worker void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
76*ec779b8eSAndroid Build Coastguard Worker {
77*ec779b8eSAndroid Build Coastguard Worker ALOGV("dataCallback");
78*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply;
79*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
80*ec779b8eSAndroid Build Coastguard Worker data.writeInt64(timestamp);
81*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(msgType);
82*ec779b8eSAndroid Build Coastguard Worker data.writeStrongBinder(IInterface::asBinder(imageData));
83*ec779b8eSAndroid Build Coastguard Worker remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
84*ec779b8eSAndroid Build Coastguard Worker }
85*ec779b8eSAndroid Build Coastguard Worker
recordingFrameHandleCallbackTimestamp(nsecs_t timestamp,native_handle_t * handle)86*ec779b8eSAndroid Build Coastguard Worker void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle) {
87*ec779b8eSAndroid Build Coastguard Worker ALOGV("recordingFrameHandleCallbackTimestamp");
88*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply;
89*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
90*ec779b8eSAndroid Build Coastguard Worker data.writeInt64(timestamp);
91*ec779b8eSAndroid Build Coastguard Worker data.writeNativeHandle(handle);
92*ec779b8eSAndroid Build Coastguard Worker remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP, data, &reply,
93*ec779b8eSAndroid Build Coastguard Worker IBinder::FLAG_ONEWAY);
94*ec779b8eSAndroid Build Coastguard Worker }
95*ec779b8eSAndroid Build Coastguard Worker
recordingFrameHandleCallbackTimestampBatch(const std::vector<nsecs_t> & timestamps,const std::vector<native_handle_t * > & handles)96*ec779b8eSAndroid Build Coastguard Worker void recordingFrameHandleCallbackTimestampBatch(
97*ec779b8eSAndroid Build Coastguard Worker const std::vector<nsecs_t>& timestamps,
98*ec779b8eSAndroid Build Coastguard Worker const std::vector<native_handle_t*>& handles) {
99*ec779b8eSAndroid Build Coastguard Worker ALOGV("recordingFrameHandleCallbackTimestampBatch");
100*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply;
101*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
102*ec779b8eSAndroid Build Coastguard Worker uint32_t n = timestamps.size();
103*ec779b8eSAndroid Build Coastguard Worker if (n != handles.size()) {
104*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: size of timestamps(%zu) and handles(%zu) mismatch!",
105*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, timestamps.size(), handles.size());
106*ec779b8eSAndroid Build Coastguard Worker return;
107*ec779b8eSAndroid Build Coastguard Worker }
108*ec779b8eSAndroid Build Coastguard Worker data.writeUint32(n);
109*ec779b8eSAndroid Build Coastguard Worker for (auto ts : timestamps) {
110*ec779b8eSAndroid Build Coastguard Worker data.writeInt64(ts);
111*ec779b8eSAndroid Build Coastguard Worker }
112*ec779b8eSAndroid Build Coastguard Worker for (auto& handle : handles) {
113*ec779b8eSAndroid Build Coastguard Worker data.writeNativeHandle(handle);
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH, data, &reply,
116*ec779b8eSAndroid Build Coastguard Worker IBinder::FLAG_ONEWAY);
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker };
119*ec779b8eSAndroid Build Coastguard Worker
120*ec779b8eSAndroid Build Coastguard Worker IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
121*ec779b8eSAndroid Build Coastguard Worker
122*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------
123*ec779b8eSAndroid Build Coastguard Worker
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)124*ec779b8eSAndroid Build Coastguard Worker status_t BnCameraClient::onTransact(
125*ec779b8eSAndroid Build Coastguard Worker uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
126*ec779b8eSAndroid Build Coastguard Worker {
127*ec779b8eSAndroid Build Coastguard Worker switch(code) {
128*ec779b8eSAndroid Build Coastguard Worker case NOTIFY_CALLBACK: {
129*ec779b8eSAndroid Build Coastguard Worker ALOGV("NOTIFY_CALLBACK");
130*ec779b8eSAndroid Build Coastguard Worker CHECK_INTERFACE(ICameraClient, data, reply);
131*ec779b8eSAndroid Build Coastguard Worker int32_t msgType = data.readInt32();
132*ec779b8eSAndroid Build Coastguard Worker int32_t ext1 = data.readInt32();
133*ec779b8eSAndroid Build Coastguard Worker int32_t ext2 = data.readInt32();
134*ec779b8eSAndroid Build Coastguard Worker notifyCallback(msgType, ext1, ext2);
135*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
136*ec779b8eSAndroid Build Coastguard Worker } break;
137*ec779b8eSAndroid Build Coastguard Worker case DATA_CALLBACK: {
138*ec779b8eSAndroid Build Coastguard Worker ALOGV("DATA_CALLBACK");
139*ec779b8eSAndroid Build Coastguard Worker CHECK_INTERFACE(ICameraClient, data, reply);
140*ec779b8eSAndroid Build Coastguard Worker int32_t msgType = data.readInt32();
141*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
142*ec779b8eSAndroid Build Coastguard Worker camera_frame_metadata_t metadata;
143*ec779b8eSAndroid Build Coastguard Worker if (data.dataAvail() > 0) {
144*ec779b8eSAndroid Build Coastguard Worker metadata.number_of_faces = data.readInt32();
145*ec779b8eSAndroid Build Coastguard Worker // Zero faces is a valid case, to notify clients that no faces are now visible
146*ec779b8eSAndroid Build Coastguard Worker if (metadata.number_of_faces < 0 ||
147*ec779b8eSAndroid Build Coastguard Worker metadata.number_of_faces > (int32_t)(INT32_MAX / sizeof(camera_face_t))) {
148*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Too large face count: %d", __FUNCTION__, metadata.number_of_faces);
149*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
150*ec779b8eSAndroid Build Coastguard Worker }
151*ec779b8eSAndroid Build Coastguard Worker metadata.faces = (camera_face_t *) data.readInplace(
152*ec779b8eSAndroid Build Coastguard Worker sizeof(camera_face_t) * metadata.number_of_faces);
153*ec779b8eSAndroid Build Coastguard Worker }
154*ec779b8eSAndroid Build Coastguard Worker dataCallback(msgType, imageData, &metadata);
155*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
156*ec779b8eSAndroid Build Coastguard Worker } break;
157*ec779b8eSAndroid Build Coastguard Worker case DATA_CALLBACK_TIMESTAMP: {
158*ec779b8eSAndroid Build Coastguard Worker ALOGV("DATA_CALLBACK_TIMESTAMP");
159*ec779b8eSAndroid Build Coastguard Worker CHECK_INTERFACE(ICameraClient, data, reply);
160*ec779b8eSAndroid Build Coastguard Worker nsecs_t timestamp = data.readInt64();
161*ec779b8eSAndroid Build Coastguard Worker int32_t msgType = data.readInt32();
162*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
163*ec779b8eSAndroid Build Coastguard Worker dataCallbackTimestamp(timestamp, msgType, imageData);
164*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
165*ec779b8eSAndroid Build Coastguard Worker } break;
166*ec779b8eSAndroid Build Coastguard Worker case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP: {
167*ec779b8eSAndroid Build Coastguard Worker ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP");
168*ec779b8eSAndroid Build Coastguard Worker CHECK_INTERFACE(ICameraClient, data, reply);
169*ec779b8eSAndroid Build Coastguard Worker nsecs_t timestamp;
170*ec779b8eSAndroid Build Coastguard Worker status_t res = data.readInt64(×tamp);
171*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
172*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to read timestamp: %s (%d)", __FUNCTION__, strerror(-res), res);
173*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
174*ec779b8eSAndroid Build Coastguard Worker }
175*ec779b8eSAndroid Build Coastguard Worker native_handle_t* handle = data.readNativeHandle();
176*ec779b8eSAndroid Build Coastguard Worker if (handle == nullptr) {
177*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Received a null native handle", __FUNCTION__);
178*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
179*ec779b8eSAndroid Build Coastguard Worker }
180*ec779b8eSAndroid Build Coastguard Worker
181*ec779b8eSAndroid Build Coastguard Worker // The native handle will be freed in BpCamera::releaseRecordingFrameHandle.
182*ec779b8eSAndroid Build Coastguard Worker recordingFrameHandleCallbackTimestamp(timestamp, handle);
183*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
184*ec779b8eSAndroid Build Coastguard Worker } break;
185*ec779b8eSAndroid Build Coastguard Worker case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH: {
186*ec779b8eSAndroid Build Coastguard Worker ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH");
187*ec779b8eSAndroid Build Coastguard Worker CHECK_INTERFACE(ICameraClient, data, reply);
188*ec779b8eSAndroid Build Coastguard Worker uint32_t n = 0;
189*ec779b8eSAndroid Build Coastguard Worker status_t res = data.readUint32(&n);
190*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
191*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
192*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker std::vector<nsecs_t> timestamps;
195*ec779b8eSAndroid Build Coastguard Worker std::vector<native_handle_t*> handles;
196*ec779b8eSAndroid Build Coastguard Worker timestamps.reserve(n);
197*ec779b8eSAndroid Build Coastguard Worker handles.reserve(n);
198*ec779b8eSAndroid Build Coastguard Worker for (uint32_t i = 0; i < n; i++) {
199*ec779b8eSAndroid Build Coastguard Worker nsecs_t t;
200*ec779b8eSAndroid Build Coastguard Worker res = data.readInt64(&t);
201*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
202*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to read timestamp[%d]: %s (%d)",
203*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, i, strerror(-res), res);
204*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
205*ec779b8eSAndroid Build Coastguard Worker }
206*ec779b8eSAndroid Build Coastguard Worker timestamps.push_back(t);
207*ec779b8eSAndroid Build Coastguard Worker }
208*ec779b8eSAndroid Build Coastguard Worker for (uint32_t i = 0; i < n; i++) {
209*ec779b8eSAndroid Build Coastguard Worker native_handle_t* handle = data.readNativeHandle();
210*ec779b8eSAndroid Build Coastguard Worker if (handle == nullptr) {
211*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Received a null native handle at handles[%d]",
212*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, i);
213*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
214*ec779b8eSAndroid Build Coastguard Worker }
215*ec779b8eSAndroid Build Coastguard Worker handles.push_back(handle);
216*ec779b8eSAndroid Build Coastguard Worker }
217*ec779b8eSAndroid Build Coastguard Worker
218*ec779b8eSAndroid Build Coastguard Worker // The native handle will be freed in BpCamera::releaseRecordingFrameHandleBatch.
219*ec779b8eSAndroid Build Coastguard Worker recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
220*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
221*ec779b8eSAndroid Build Coastguard Worker } break;
222*ec779b8eSAndroid Build Coastguard Worker default:
223*ec779b8eSAndroid Build Coastguard Worker return BBinder::onTransact(code, data, reply, flags);
224*ec779b8eSAndroid Build Coastguard Worker }
225*ec779b8eSAndroid Build Coastguard Worker }
226*ec779b8eSAndroid Build Coastguard Worker
227*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
228*ec779b8eSAndroid Build Coastguard Worker
229*ec779b8eSAndroid Build Coastguard Worker } // namespace hardware
230*ec779b8eSAndroid Build Coastguard Worker } // namespace android
231