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