1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ICameraRecordingProxy"
19#include <camera/CameraUtils.h>
20#include <camera/ICameraRecordingProxy.h>
21#include <camera/ICameraRecordingProxyListener.h>
22#include <binder/IMemory.h>
23#include <binder/Parcel.h>
24#include <media/hardware/HardwareAPI.h>
25#include <stdint.h>
26#include <utils/Log.h>
27
28namespace android {
29
30enum {
31    START_RECORDING = IBinder::FIRST_CALL_TRANSACTION,
32    STOP_RECORDING,
33    RELEASE_RECORDING_FRAME,
34    RELEASE_RECORDING_FRAME_HANDLE,
35    RELEASE_RECORDING_FRAME_HANDLE_BATCH,
36};
37
38
39class BpCameraRecordingProxy: public BpInterface<ICameraRecordingProxy>
40{
41public:
42    explicit BpCameraRecordingProxy(const sp<IBinder>& impl)
43        : BpInterface<ICameraRecordingProxy>(impl)
44    {
45    }
46
47    status_t startRecording(const sp<ICameraRecordingProxyListener>& listener)
48    {
49        ALOGV("startRecording");
50        Parcel data, reply;
51        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
52        data.writeStrongBinder(IInterface::asBinder(listener));
53        remote()->transact(START_RECORDING, data, &reply);
54        return reply.readInt32();
55    }
56
57    void stopRecording()
58    {
59        ALOGV("stopRecording");
60        Parcel data, reply;
61        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
62        remote()->transact(STOP_RECORDING, data, &reply);
63    }
64
65    void releaseRecordingFrame(const sp<IMemory>& mem)
66    {
67        ALOGV("releaseRecordingFrame");
68        Parcel data, reply;
69        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
70        data.writeStrongBinder(IInterface::asBinder(mem));
71        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
72    }
73
74    void releaseRecordingFrameHandle(native_handle_t *handle) {
75        ALOGV("releaseRecordingFrameHandle");
76        Parcel data, reply;
77        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
78        data.writeNativeHandle(handle);
79
80        remote()->transact(RELEASE_RECORDING_FRAME_HANDLE, data, &reply);
81
82        // Close the native handle because camera received a dup copy.
83        native_handle_close(handle);
84        native_handle_delete(handle);
85    }
86
87    void releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
88        ALOGV("releaseRecordingFrameHandleBatch");
89        Parcel data, reply;
90        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
91        uint32_t n = handles.size();
92        data.writeUint32(n);
93        for (auto& handle : handles) {
94            data.writeNativeHandle(handle);
95        }
96        remote()->transact(RELEASE_RECORDING_FRAME_HANDLE_BATCH, data, &reply);
97
98        // Close the native handle because camera received a dup copy.
99        for (auto& handle : handles) {
100            native_handle_close(handle);
101            native_handle_delete(handle);
102        }
103    }
104};
105
106IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy");
107
108// ----------------------------------------------------------------------
109
110status_t BnCameraRecordingProxy::onTransact(
111    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
112{
113    switch(code) {
114        case START_RECORDING: {
115            ALOGV("START_RECORDING");
116            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
117            sp<ICameraRecordingProxyListener> listener =
118                interface_cast<ICameraRecordingProxyListener>(data.readStrongBinder());
119            reply->writeInt32(startRecording(listener));
120            return NO_ERROR;
121        } break;
122        case STOP_RECORDING: {
123            ALOGV("STOP_RECORDING");
124            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
125            stopRecording();
126            return NO_ERROR;
127        } break;
128        case RELEASE_RECORDING_FRAME: {
129            ALOGV("RELEASE_RECORDING_FRAME");
130            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
131            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
132            releaseRecordingFrame(mem);
133            return NO_ERROR;
134        } break;
135        case RELEASE_RECORDING_FRAME_HANDLE: {
136            ALOGV("RELEASE_RECORDING_FRAME_HANDLE");
137            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
138
139            // releaseRecordingFrameHandle will be responsble to close the native handle.
140            releaseRecordingFrameHandle(data.readNativeHandle());
141            return NO_ERROR;
142        } break;
143        case RELEASE_RECORDING_FRAME_HANDLE_BATCH: {
144            ALOGV("RELEASE_RECORDING_FRAME_HANDLE_BATCH");
145            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
146            uint32_t n = 0;
147            status_t res = data.readUint32(&n);
148            if (res != OK) {
149                ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
150                return BAD_VALUE;
151            }
152            std::vector<native_handle_t*> handles;
153            handles.reserve(n);
154            for (uint32_t i = 0; i < n; i++) {
155                native_handle_t* handle = data.readNativeHandle();
156                if (handle == nullptr) {
157                    ALOGE("%s: Received a null native handle at handles[%d]",
158                            __FUNCTION__, i);
159                    return BAD_VALUE;
160                }
161                handles.push_back(handle);
162            }
163
164            // releaseRecordingFrameHandleBatch will be responsble to close the native handle.
165            releaseRecordingFrameHandleBatch(handles);
166            return NO_ERROR;
167        } break;
168        default:
169            return BBinder::onTransact(code, data, reply, flags);
170    }
171}
172
173// ----------------------------------------------------------------------------
174
175}; // namespace android
176
177