14ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li/*
24ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * Copyright (C) 2011 The Android Open Source Project
34ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li *
44ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * Licensed under the Apache License, Version 2.0 (the "License");
54ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * you may not use this file except in compliance with the License.
64ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * You may obtain a copy of the License at
74ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li *
84ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li *      http://www.apache.org/licenses/LICENSE-2.0
94ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li *
104ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * Unless required by applicable law or agreed to in writing, software
114ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * distributed under the License is distributed on an "AS IS" BASIS,
124ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * See the License for the specific language governing permissions and
144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li * limitations under the License.
154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li */
164ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li//#define LOG_NDEBUG 0
184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#define LOG_TAG "ICameraRecordingProxyListener"
196773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan#include <camera/CameraUtils.h>
204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <camera/ICameraRecordingProxyListener.h>
214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <binder/IMemory.h>
224ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <binder/Parcel.h>
236773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan#include <media/hardware/HardwareAPI.h>
244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <utils/Log.h>
254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
264ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Linamespace android {
274ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
284ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Lienum {
294ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    DATA_CALLBACK_TIMESTAMP = IBinder::FIRST_CALL_TRANSACTION,
302d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP,
31b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh    RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH
324ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li};
334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
344ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Liclass BpCameraRecordingProxyListener: public BpInterface<ICameraRecordingProxyListener>
354ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li{
364ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Lipublic:
37090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BpCameraRecordingProxyListener(const sp<IBinder>& impl)
384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        : BpInterface<ICameraRecordingProxyListener>(impl)
394ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    {
404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
414ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
424ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
434ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    {
443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallback");
454ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        Parcel data, reply;
464ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
474ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        data.writeInt64(timestamp);
484ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        data.writeInt32(msgType);
4906b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        data.writeStrongBinder(IInterface::asBinder(imageData));
504ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
532d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle) {
542d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        ALOGV("recordingFrameHandleCallbackTimestamp");
552d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        Parcel data, reply;
562d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
572d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        data.writeInt64(timestamp);
582d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        data.writeNativeHandle(handle);
592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP, data, &reply,
602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                IBinder::FLAG_ONEWAY);
616773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan
626773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan        // The native handle is dupped in ICameraClient so we need to free it here.
632d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_close(handle);
642d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_delete(handle);
654ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
66b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh
67b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh    void recordingFrameHandleCallbackTimestampBatch(
68b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            const std::vector<nsecs_t>& timestamps,
69b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            const std::vector<native_handle_t*>& handles) {
70b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        ALOGV("recordingFrameHandleCallbackTimestampBatch");
71b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        Parcel data, reply;
72b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
73b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh
74b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        uint32_t n = timestamps.size();
75b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        if (n != handles.size()) {
76b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            ALOGE("%s: size of timestamps(%zu) and handles(%zu) mismatch!",
77b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    __FUNCTION__, timestamps.size(), handles.size());
78b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            return;
79b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        }
80b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        data.writeUint32(n);
81b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        for (auto ts : timestamps) {
82b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            data.writeInt64(ts);
83b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        }
84b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        for (auto& handle : handles) {
85b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            data.writeNativeHandle(handle);
86b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        }
87b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH, data, &reply,
88b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                IBinder::FLAG_ONEWAY);
89b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh
90b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        // The native handle is dupped in ICameraClient so we need to free it here.
91b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        for (auto& handle : handles) {
92b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            native_handle_close(handle);
93b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            native_handle_delete(handle);
94b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        }
95b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh    }
964ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li};
974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
984ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiIMPLEMENT_META_INTERFACE(CameraRecordingProxyListener, "android.hardware.ICameraRecordingProxyListener");
994ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1004ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li// ----------------------------------------------------------------------
1014ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1024ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Listatus_t BnCameraRecordingProxyListener::onTransact(
1034ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1044ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li{
1054ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    switch(code) {
1064ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        case DATA_CALLBACK_TIMESTAMP: {
1073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("DATA_CALLBACK_TIMESTAMP");
1084ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
1094ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            nsecs_t timestamp = data.readInt64();
1104ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            int32_t msgType = data.readInt32();
1114ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
1122d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            dataCallbackTimestamp(timestamp, msgType, imageData);
1132d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            return NO_ERROR;
1142d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        } break;
1152d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP: {
1162d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP");
1172d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
1182d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            nsecs_t timestamp;
1192d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            status_t res = data.readInt64(&timestamp);
1202d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            if (res != OK) {
1212d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                ALOGE("%s: Failed to read timestamp: %s (%d)", __FUNCTION__, strerror(-res), res);
1222d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                return BAD_VALUE;
1236773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan            }
1246773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan
1252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            native_handle_t* handle = data.readNativeHandle();
1262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            if (handle == nullptr) {
1272d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                ALOGE("%s: Received a null native handle", __FUNCTION__);
1282d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                return BAD_VALUE;
1292d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            }
1302d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // The native handle will be freed in
1312d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // BpCameraRecordingProxy::releaseRecordingFrameHandle.
1322d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            recordingFrameHandleCallbackTimestamp(timestamp, handle);
1334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return NO_ERROR;
1344ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        } break;
135b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH: {
136b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH");
137b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
138b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            uint32_t n = 0;
139b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            status_t res = data.readUint32(&n);
140b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            if (res != OK) {
141b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
142b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                return BAD_VALUE;
143b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            }
144b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            std::vector<nsecs_t> timestamps;
145b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            std::vector<native_handle_t*> handles;
146b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            timestamps.reserve(n);
147b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            handles.reserve(n);
148b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            for (uint32_t i = 0; i < n; i++) {
149b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                res = data.readInt64(&timestamps[i]);
150b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                if (res != OK) {
151b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    ALOGE("%s: Failed to read timestamp[%d]: %s (%d)",
152b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                            __FUNCTION__, i, strerror(-res), res);
153b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    return BAD_VALUE;
154b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                }
155b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            }
156b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            for (uint32_t i = 0; i < n; i++) {
157b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                native_handle_t* handle = data.readNativeHandle();
158b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                if (handle == nullptr) {
159b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    ALOGE("%s: Received a null native handle at handles[%d]",
160b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                            __FUNCTION__, i);
161b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    return BAD_VALUE;
162b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                }
163b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                handles.push_back(handle);
164b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            }
165b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            // The native handle will be freed in
166b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            // BpCameraRecordingProxy::releaseRecordingFrameHandleBatch.
167b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
168b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            return NO_ERROR;
169b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        } break;
1704ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        default:
1714ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return BBinder::onTransact(code, data, reply, flags);
1724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
1734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
1744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li// ----------------------------------------------------------------------------
1764ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1774ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}; // namespace android
1784ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
179