1 /*
2 **
3 ** Copyright 2013, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 // #define LOG_NDEBUG 0
19 #define LOG_TAG "IProCameraUser"
20 #include <utils/Log.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <binder/Parcel.h>
24 #include <camera/IProCameraUser.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <gui/Surface.h>
27 #include "camera/CameraMetadata.h"
28
29 namespace android {
30
31 enum {
32 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
33 CONNECT,
34 EXCLUSIVE_TRY_LOCK,
35 EXCLUSIVE_LOCK,
36 EXCLUSIVE_UNLOCK,
37 HAS_EXCLUSIVE_LOCK,
38 SUBMIT_REQUEST,
39 CANCEL_REQUEST,
40 DELETE_STREAM,
41 CREATE_STREAM,
42 CREATE_DEFAULT_REQUEST,
43 GET_CAMERA_INFO,
44 };
45
46 class BpProCameraUser: public BpInterface<IProCameraUser>
47 {
48 public:
BpProCameraUser(const sp<IBinder> & impl)49 BpProCameraUser(const sp<IBinder>& impl)
50 : BpInterface<IProCameraUser>(impl)
51 {
52 }
53
54 // disconnect from camera service
disconnect()55 void disconnect()
56 {
57 ALOGV("disconnect");
58 Parcel data, reply;
59 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
60 remote()->transact(DISCONNECT, data, &reply);
61 reply.readExceptionCode();
62 }
63
connect(const sp<IProCameraCallbacks> & cameraClient)64 virtual status_t connect(const sp<IProCameraCallbacks>& cameraClient)
65 {
66 Parcel data, reply;
67 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
68 data.writeStrongBinder(cameraClient->asBinder());
69 remote()->transact(CONNECT, data, &reply);
70 return reply.readInt32();
71 }
72
73 /* Shared ProCameraUser */
74
exclusiveTryLock()75 virtual status_t exclusiveTryLock()
76 {
77 Parcel data, reply;
78 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
79 remote()->transact(EXCLUSIVE_TRY_LOCK, data, &reply);
80 return reply.readInt32();
81 }
exclusiveLock()82 virtual status_t exclusiveLock()
83 {
84 Parcel data, reply;
85 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
86 remote()->transact(EXCLUSIVE_LOCK, data, &reply);
87 return reply.readInt32();
88 }
89
exclusiveUnlock()90 virtual status_t exclusiveUnlock()
91 {
92 Parcel data, reply;
93 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
94 remote()->transact(EXCLUSIVE_UNLOCK, data, &reply);
95 return reply.readInt32();
96 }
97
hasExclusiveLock()98 virtual bool hasExclusiveLock()
99 {
100 Parcel data, reply;
101 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
102 remote()->transact(HAS_EXCLUSIVE_LOCK, data, &reply);
103 return !!reply.readInt32();
104 }
105
submitRequest(camera_metadata_t * metadata,bool streaming)106 virtual int submitRequest(camera_metadata_t* metadata, bool streaming)
107 {
108
109 Parcel data, reply;
110 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
111
112 // arg0+arg1
113 CameraMetadata::writeToParcel(data, metadata);
114
115 // arg2 = streaming (bool)
116 data.writeInt32(streaming);
117
118 remote()->transact(SUBMIT_REQUEST, data, &reply);
119 return reply.readInt32();
120 }
121
cancelRequest(int requestId)122 virtual status_t cancelRequest(int requestId)
123 {
124 Parcel data, reply;
125 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
126 data.writeInt32(requestId);
127
128 remote()->transact(CANCEL_REQUEST, data, &reply);
129 return reply.readInt32();
130 }
131
deleteStream(int streamId)132 virtual status_t deleteStream(int streamId)
133 {
134 Parcel data, reply;
135 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
136 data.writeInt32(streamId);
137
138 remote()->transact(DELETE_STREAM, data, &reply);
139 return reply.readInt32();
140 }
141
createStream(int width,int height,int format,const sp<IGraphicBufferProducer> & bufferProducer,int * streamId)142 virtual status_t createStream(int width, int height, int format,
143 const sp<IGraphicBufferProducer>& bufferProducer,
144 /*out*/
145 int* streamId)
146 {
147 Parcel data, reply;
148 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
149 data.writeInt32(width);
150 data.writeInt32(height);
151 data.writeInt32(format);
152
153 sp<IBinder> b(bufferProducer->asBinder());
154 data.writeStrongBinder(b);
155
156 remote()->transact(CREATE_STREAM, data, &reply);
157
158 int sId = reply.readInt32();
159 if (streamId) {
160 *streamId = sId;
161 }
162 return reply.readInt32();
163 }
164
165 // Create a request object from a template.
createDefaultRequest(int templateId,camera_metadata ** request)166 virtual status_t createDefaultRequest(int templateId,
167 /*out*/
168 camera_metadata** request)
169 {
170 Parcel data, reply;
171 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
172 data.writeInt32(templateId);
173 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
174 CameraMetadata::readFromParcel(reply, /*out*/request);
175 return reply.readInt32();
176 }
177
178
getCameraInfo(int cameraId,camera_metadata ** info)179 virtual status_t getCameraInfo(int cameraId, camera_metadata** info)
180 {
181 Parcel data, reply;
182 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
183 data.writeInt32(cameraId);
184 remote()->transact(GET_CAMERA_INFO, data, &reply);
185 CameraMetadata::readFromParcel(reply, /*out*/info);
186 return reply.readInt32();
187 }
188
189
190 private:
191
192
193 };
194
195 IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser");
196
197 // ----------------------------------------------------------------------
198
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)199 status_t BnProCameraUser::onTransact(
200 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
201 {
202 switch(code) {
203 case DISCONNECT: {
204 ALOGV("DISCONNECT");
205 CHECK_INTERFACE(IProCameraUser, data, reply);
206 disconnect();
207 reply->writeNoException();
208 return NO_ERROR;
209 } break;
210 case CONNECT: {
211 CHECK_INTERFACE(IProCameraUser, data, reply);
212 sp<IProCameraCallbacks> cameraClient =
213 interface_cast<IProCameraCallbacks>(data.readStrongBinder());
214 reply->writeInt32(connect(cameraClient));
215 return NO_ERROR;
216 } break;
217
218 /* Shared ProCameraUser */
219 case EXCLUSIVE_TRY_LOCK: {
220 CHECK_INTERFACE(IProCameraUser, data, reply);
221 reply->writeInt32(exclusiveTryLock());
222 return NO_ERROR;
223 } break;
224 case EXCLUSIVE_LOCK: {
225 CHECK_INTERFACE(IProCameraUser, data, reply);
226 reply->writeInt32(exclusiveLock());
227 return NO_ERROR;
228 } break;
229 case EXCLUSIVE_UNLOCK: {
230 CHECK_INTERFACE(IProCameraUser, data, reply);
231 reply->writeInt32(exclusiveUnlock());
232 return NO_ERROR;
233 } break;
234 case HAS_EXCLUSIVE_LOCK: {
235 CHECK_INTERFACE(IProCameraUser, data, reply);
236 reply->writeInt32(hasExclusiveLock());
237 return NO_ERROR;
238 } break;
239 case SUBMIT_REQUEST: {
240 CHECK_INTERFACE(IProCameraUser, data, reply);
241 camera_metadata_t* metadata;
242 CameraMetadata::readFromParcel(data, /*out*/&metadata);
243
244 // arg2 = streaming (bool)
245 bool streaming = data.readInt32();
246
247 // return code: requestId (int32)
248 reply->writeInt32(submitRequest(metadata, streaming));
249
250 return NO_ERROR;
251 } break;
252 case CANCEL_REQUEST: {
253 CHECK_INTERFACE(IProCameraUser, data, reply);
254 int requestId = data.readInt32();
255 reply->writeInt32(cancelRequest(requestId));
256 return NO_ERROR;
257 } break;
258 case DELETE_STREAM: {
259 CHECK_INTERFACE(IProCameraUser, data, reply);
260 int streamId = data.readInt32();
261 reply->writeInt32(deleteStream(streamId));
262 return NO_ERROR;
263 } break;
264 case CREATE_STREAM: {
265 CHECK_INTERFACE(IProCameraUser, data, reply);
266 int width, height, format;
267
268 width = data.readInt32();
269 height = data.readInt32();
270 format = data.readInt32();
271
272 sp<IGraphicBufferProducer> bp =
273 interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
274
275 int streamId = -1;
276 status_t ret;
277 ret = createStream(width, height, format, bp, &streamId);
278
279 reply->writeInt32(streamId);
280 reply->writeInt32(ret);
281
282 return NO_ERROR;
283 } break;
284
285 case CREATE_DEFAULT_REQUEST: {
286 CHECK_INTERFACE(IProCameraUser, data, reply);
287
288 int templateId = data.readInt32();
289
290 camera_metadata_t* request = NULL;
291 status_t ret;
292 ret = createDefaultRequest(templateId, &request);
293
294 CameraMetadata::writeToParcel(*reply, request);
295 reply->writeInt32(ret);
296
297 free_camera_metadata(request);
298
299 return NO_ERROR;
300 } break;
301 case GET_CAMERA_INFO: {
302 CHECK_INTERFACE(IProCameraUser, data, reply);
303
304 int cameraId = data.readInt32();
305
306 camera_metadata_t* info = NULL;
307 status_t ret;
308 ret = getCameraInfo(cameraId, &info);
309
310 CameraMetadata::writeToParcel(*reply, info);
311 reply->writeInt32(ret);
312
313 free_camera_metadata(info);
314
315 return NO_ERROR;
316 } break;
317 default:
318 return BBinder::onTransact(code, data, reply, flags);
319 }
320 }
321
322 // ----------------------------------------------------------------------------
323
324 }; // namespace android
325