OSDN Git Service

aaudio: fix hang in client when audioserver dies
[android-x86/frameworks-av.git] / camera / ICameraRecordingProxyListener.cpp
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 "ICameraRecordingProxyListener"
19 #include <camera/CameraUtils.h>
20 #include <camera/ICameraRecordingProxyListener.h>
21 #include <binder/IMemory.h>
22 #include <binder/Parcel.h>
23 #include <media/hardware/HardwareAPI.h>
24 #include <utils/Log.h>
25
26 namespace android {
27
28 enum {
29     DATA_CALLBACK_TIMESTAMP = IBinder::FIRST_CALL_TRANSACTION,
30     RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP,
31     RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH
32 };
33
34 class BpCameraRecordingProxyListener: public BpInterface<ICameraRecordingProxyListener>
35 {
36 public:
37     explicit BpCameraRecordingProxyListener(const sp<IBinder>& impl)
38         : BpInterface<ICameraRecordingProxyListener>(impl)
39     {
40     }
41
42     void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
43     {
44         ALOGV("dataCallback");
45         Parcel data, reply;
46         data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
47         data.writeInt64(timestamp);
48         data.writeInt32(msgType);
49         data.writeStrongBinder(IInterface::asBinder(imageData));
50         remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
51     }
52
53     void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle) {
54         ALOGV("recordingFrameHandleCallbackTimestamp");
55         Parcel data, reply;
56         data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
57         data.writeInt64(timestamp);
58         data.writeNativeHandle(handle);
59         remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP, data, &reply,
60                 IBinder::FLAG_ONEWAY);
61
62         // The native handle is dupped in ICameraClient so we need to free it here.
63         native_handle_close(handle);
64         native_handle_delete(handle);
65     }
66
67     void recordingFrameHandleCallbackTimestampBatch(
68             const std::vector<nsecs_t>& timestamps,
69             const std::vector<native_handle_t*>& handles) {
70         ALOGV("recordingFrameHandleCallbackTimestampBatch");
71         Parcel data, reply;
72         data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
73
74         uint32_t n = timestamps.size();
75         if (n != handles.size()) {
76             ALOGE("%s: size of timestamps(%zu) and handles(%zu) mismatch!",
77                     __FUNCTION__, timestamps.size(), handles.size());
78             return;
79         }
80         data.writeUint32(n);
81         for (auto ts : timestamps) {
82             data.writeInt64(ts);
83         }
84         for (auto& handle : handles) {
85             data.writeNativeHandle(handle);
86         }
87         remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH, data, &reply,
88                 IBinder::FLAG_ONEWAY);
89
90         // The native handle is dupped in ICameraClient so we need to free it here.
91         for (auto& handle : handles) {
92             native_handle_close(handle);
93             native_handle_delete(handle);
94         }
95     }
96 };
97
98 IMPLEMENT_META_INTERFACE(CameraRecordingProxyListener, "android.hardware.ICameraRecordingProxyListener");
99
100 // ----------------------------------------------------------------------
101
102 status_t BnCameraRecordingProxyListener::onTransact(
103     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
104 {
105     switch(code) {
106         case DATA_CALLBACK_TIMESTAMP: {
107             ALOGV("DATA_CALLBACK_TIMESTAMP");
108             CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
109             nsecs_t timestamp = data.readInt64();
110             int32_t msgType = data.readInt32();
111             sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
112             dataCallbackTimestamp(timestamp, msgType, imageData);
113             return NO_ERROR;
114         } break;
115         case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP: {
116             ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP");
117             CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
118             nsecs_t timestamp;
119             status_t res = data.readInt64(&timestamp);
120             if (res != OK) {
121                 ALOGE("%s: Failed to read timestamp: %s (%d)", __FUNCTION__, strerror(-res), res);
122                 return BAD_VALUE;
123             }
124
125             native_handle_t* handle = data.readNativeHandle();
126             if (handle == nullptr) {
127                 ALOGE("%s: Received a null native handle", __FUNCTION__);
128                 return BAD_VALUE;
129             }
130             // The native handle will be freed in
131             // BpCameraRecordingProxy::releaseRecordingFrameHandle.
132             recordingFrameHandleCallbackTimestamp(timestamp, handle);
133             return NO_ERROR;
134         } break;
135         case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH: {
136             ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH");
137             CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
138             uint32_t n = 0;
139             status_t res = data.readUint32(&n);
140             if (res != OK) {
141                 ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
142                 return BAD_VALUE;
143             }
144             std::vector<nsecs_t> timestamps;
145             std::vector<native_handle_t*> handles;
146             timestamps.reserve(n);
147             handles.reserve(n);
148             for (uint32_t i = 0; i < n; i++) {
149                 res = data.readInt64(&timestamps[i]);
150                 if (res != OK) {
151                     ALOGE("%s: Failed to read timestamp[%d]: %s (%d)",
152                             __FUNCTION__, i, strerror(-res), res);
153                     return BAD_VALUE;
154                 }
155             }
156             for (uint32_t i = 0; i < n; i++) {
157                 native_handle_t* handle = data.readNativeHandle();
158                 if (handle == nullptr) {
159                     ALOGE("%s: Received a null native handle at handles[%d]",
160                             __FUNCTION__, i);
161                     return BAD_VALUE;
162                 }
163                 handles.push_back(handle);
164             }
165             // The native handle will be freed in
166             // BpCameraRecordingProxy::releaseRecordingFrameHandleBatch.
167             recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
168             return NO_ERROR;
169         } break;
170         default:
171             return BBinder::onTransact(code, data, reply, flags);
172     }
173 }
174
175 // ----------------------------------------------------------------------------
176
177 }; // namespace android
178