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 "ICameraRecordingProxy"
196773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan#include <camera/CameraUtils.h>
204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <camera/ICameraRecordingProxy.h>
214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <camera/ICameraRecordingProxyListener.h>
224ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <binder/IMemory.h>
234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <binder/Parcel.h>
246773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan#include <media/hardware/HardwareAPI.h>
254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <stdint.h>
264ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li#include <utils/Log.h>
274ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
284ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Linamespace android {
294ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Lienum {
314ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    START_RECORDING = IBinder::FIRST_CALL_TRANSACTION,
324ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    STOP_RECORDING,
334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    RELEASE_RECORDING_FRAME,
342d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    RELEASE_RECORDING_FRAME_HANDLE,
35b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh    RELEASE_RECORDING_FRAME_HANDLE_BATCH,
364ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li};
374ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
394ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Liclass BpCameraRecordingProxy: public BpInterface<ICameraRecordingProxy>
404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li{
414ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Lipublic:
42090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BpCameraRecordingProxy(const sp<IBinder>& impl)
434ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        : BpInterface<ICameraRecordingProxy>(impl)
444ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    {
454ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
464ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
474ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    status_t startRecording(const sp<ICameraRecordingProxyListener>& listener)
484ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    {
493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("startRecording");
504ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        Parcel data, reply;
514ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
5206b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        data.writeStrongBinder(IInterface::asBinder(listener));
534ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        remote()->transact(START_RECORDING, data, &reply);
544ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        return reply.readInt32();
554ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
564ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
574ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    void stopRecording()
584ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    {
593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("stopRecording");
604ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        Parcel data, reply;
614ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
624ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        remote()->transact(STOP_RECORDING, data, &reply);
634ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
644ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
654ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    void releaseRecordingFrame(const sp<IMemory>& mem)
664ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    {
673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("releaseRecordingFrame");
684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        Parcel data, reply;
694ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
7006b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        data.writeStrongBinder(IInterface::asBinder(mem));
712d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
722d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
736773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan
742d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    void releaseRecordingFrameHandle(native_handle_t *handle) {
752d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        ALOGV("releaseRecordingFrameHandle");
762d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        Parcel data, reply;
772d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
782d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        data.writeNativeHandle(handle);
796773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan
802d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        remote()->transact(RELEASE_RECORDING_FRAME_HANDLE, data, &reply);
816773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan
822d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        // Close the native handle because camera received a dup copy.
832d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_close(handle);
842d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_delete(handle);
854ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
86b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh
87b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh    void releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
88b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        ALOGV("releaseRecordingFrameHandleBatch");
89b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        Parcel data, reply;
90b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
91b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        uint32_t n = handles.size();
92b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        data.writeUint32(n);
93b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        for (auto& handle : handles) {
94b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            data.writeNativeHandle(handle);
95b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        }
96b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        remote()->transact(RELEASE_RECORDING_FRAME_HANDLE_BATCH, data, &reply);
97b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh
98b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        // Close the native handle because camera received a dup copy.
99b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        for (auto& handle : handles) {
100b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            native_handle_close(handle);
101b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            native_handle_delete(handle);
102b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        }
103b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh    }
1044ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li};
1054ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1064ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiIMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy");
1074ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1084ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li// ----------------------------------------------------------------------
1094ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1104ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Listatus_t BnCameraRecordingProxy::onTransact(
1114ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1124ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li{
1134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    switch(code) {
1144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        case START_RECORDING: {
1153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("START_RECORDING");
1164ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
1174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            sp<ICameraRecordingProxyListener> listener =
1184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                interface_cast<ICameraRecordingProxyListener>(data.readStrongBinder());
1194ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            reply->writeInt32(startRecording(listener));
1204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return NO_ERROR;
1214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        } break;
1224ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        case STOP_RECORDING: {
1233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("STOP_RECORDING");
1244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
1254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            stopRecording();
1264ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return NO_ERROR;
1274ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        } break;
1284ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        case RELEASE_RECORDING_FRAME: {
1293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("RELEASE_RECORDING_FRAME");
1304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
1314ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
1324ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            releaseRecordingFrame(mem);
1334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return NO_ERROR;
1344ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        } break;
1352d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        case RELEASE_RECORDING_FRAME_HANDLE: {
1362d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            ALOGV("RELEASE_RECORDING_FRAME_HANDLE");
1372d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
1384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1392d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // releaseRecordingFrameHandle will be responsble to close the native handle.
1402d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            releaseRecordingFrameHandle(data.readNativeHandle());
1412d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            return NO_ERROR;
1422d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        } break;
143b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        case RELEASE_RECORDING_FRAME_HANDLE_BATCH: {
144b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            ALOGV("RELEASE_RECORDING_FRAME_HANDLE_BATCH");
145b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
146b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            uint32_t n = 0;
147b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            status_t res = data.readUint32(&n);
148b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            if (res != OK) {
149b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
150b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                return BAD_VALUE;
151b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            }
152b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            std::vector<native_handle_t*> handles;
153b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            handles.reserve(n);
154b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            for (uint32_t i = 0; i < n; i++) {
155b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                native_handle_t* handle = data.readNativeHandle();
156b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                if (handle == nullptr) {
157b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    ALOGE("%s: Received a null native handle at handles[%d]",
158b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                            __FUNCTION__, i);
159b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                    return BAD_VALUE;
160b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                }
161b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh                handles.push_back(handle);
162b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            }
163b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh
164b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            // releaseRecordingFrameHandleBatch will be responsble to close the native handle.
165b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            releaseRecordingFrameHandleBatch(handles);
166b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh            return NO_ERROR;
167b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh        } break;
1684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        default:
1694ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return BBinder::onTransact(code, data, reply, flags);
1704ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
1714ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
1724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li// ----------------------------------------------------------------------------
1744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
1754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}; // namespace android
1764ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
177