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 
28 namespace android {
29 
30 enum {
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 
39 class BpCameraRecordingProxy: public BpInterface<ICameraRecordingProxy>
40 {
41 public:
BpCameraRecordingProxy(const sp<IBinder> & impl)42     explicit BpCameraRecordingProxy(const sp<IBinder>& impl)
43         : BpInterface<ICameraRecordingProxy>(impl)
44     {
45     }
46 
startRecording(const sp<ICameraRecordingProxyListener> & listener)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 
stopRecording()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 
releaseRecordingFrame(const sp<IMemory> & mem)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 
releaseRecordingFrameHandle(native_handle_t * handle)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 
releaseRecordingFrameHandleBatch(const std::vector<native_handle_t * > & handles)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 
106 IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy");
107 
108 // ----------------------------------------------------------------------
109 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)110 status_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