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: 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 106 IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy"); 107 108 // ---------------------------------------------------------------------- 109 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