blob: 76c2dcd4ff6d7bddbea892eec3a4c9c244b4b39d [file] [log] [blame]
Igor Murashkin634a5152013-02-20 17:15:11 -08001/*
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 <system/camera_metadata.h>
28
29namespace android {
30
31typedef Parcel::WritableBlob WritableBlob;
32typedef Parcel::ReadableBlob ReadableBlob;
33
34enum {
35 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
36 CONNECT,
37 EXCLUSIVE_TRY_LOCK,
38 EXCLUSIVE_LOCK,
39 EXCLUSIVE_UNLOCK,
40 HAS_EXCLUSIVE_LOCK,
41 SUBMIT_REQUEST,
42 CANCEL_REQUEST,
43 REQUEST_STREAM,
44 CANCEL_STREAM,
45};
46
47class BpProCameraUser: public BpInterface<IProCameraUser>
48{
49public:
50 BpProCameraUser(const sp<IBinder>& impl)
51 : BpInterface<IProCameraUser>(impl)
52 {
53 }
54
55 // disconnect from camera service
56 void disconnect()
57 {
58 ALOGV("disconnect");
59 Parcel data, reply;
60 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
61 remote()->transact(DISCONNECT, data, &reply);
62 }
63
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
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 }
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
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
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
106 virtual int submitRequest(camera_metadata_t* metadata, bool streaming)
107 {
108
109 Parcel data, reply;
110 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
111
112 // arg0 = metadataSize (int32)
113 size_t metadataSize = get_camera_metadata_compact_size(metadata);
114 data.writeInt32(static_cast<int32_t>(metadataSize));
115
116 // arg1 = metadata (blob)
117 WritableBlob blob;
118 {
119 data.writeBlob(metadataSize, &blob);
120 copy_camera_metadata(blob.data(), metadataSize, metadata);
121 }
122 blob.release();
123
124 // arg2 = streaming (bool)
125 data.writeInt32(streaming);
126
127 remote()->transact(SUBMIT_REQUEST, data, &reply);
128 return reply.readInt32();
129 }
130
131 virtual status_t cancelRequest(int requestId)
132 {
133 Parcel data, reply;
134 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
135 data.writeInt32(requestId);
136
137 remote()->transact(CANCEL_REQUEST, data, &reply);
138 return reply.readInt32();
139 }
140
141 virtual status_t requestStream(int streamId)
142 {
143 Parcel data, reply;
144 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
145 data.writeInt32(streamId);
146
147 remote()->transact(REQUEST_STREAM, data, &reply);
148 return reply.readInt32();
149 }
150 virtual status_t cancelStream(int streamId)
151 {
152 Parcel data, reply;
153 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
154 data.writeInt32(streamId);
155
156 remote()->transact(CANCEL_STREAM, data, &reply);
157 return reply.readInt32();
158 }
159
160};
161
162IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser");
163
164// ----------------------------------------------------------------------
165
166status_t BnProCameraUser::onTransact(
167 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
168{
169 switch(code) {
170 case DISCONNECT: {
171 ALOGV("DISCONNECT");
172 CHECK_INTERFACE(IProCameraUser, data, reply);
173 disconnect();
174 return NO_ERROR;
175 } break;
176 case CONNECT: {
177 CHECK_INTERFACE(IProCameraUser, data, reply);
178 sp<IProCameraCallbacks> cameraClient =
179 interface_cast<IProCameraCallbacks>(data.readStrongBinder());
180 reply->writeInt32(connect(cameraClient));
181 return NO_ERROR;
182 } break;
183
184 /* Shared ProCameraUser */
185 case EXCLUSIVE_TRY_LOCK: {
186 CHECK_INTERFACE(IProCameraUser, data, reply);
187 reply->writeInt32(exclusiveTryLock());
188 return NO_ERROR;
189 } break;
190 case EXCLUSIVE_LOCK: {
191 CHECK_INTERFACE(IProCameraUser, data, reply);
192 reply->writeInt32(exclusiveLock());
193 return NO_ERROR;
194 } break;
195 case EXCLUSIVE_UNLOCK: {
196 CHECK_INTERFACE(IProCameraUser, data, reply);
197 reply->writeInt32(exclusiveUnlock());
198 return NO_ERROR;
199 } break;
200 case HAS_EXCLUSIVE_LOCK: {
201 CHECK_INTERFACE(IProCameraUser, data, reply);
202 reply->writeInt32(hasExclusiveLock());
203 return NO_ERROR;
204 } break;
205 case SUBMIT_REQUEST: {
206 CHECK_INTERFACE(IProCameraUser, data, reply);
207 camera_metadata_t* metadata;
208
209 // arg0 = metadataSize (int32)
210 size_t metadataSize = static_cast<size_t>(data.readInt32());
211
212 // NOTE: this doesn't make sense to me. shouldnt the blob
213 // know how big it is? why do we have to specify the size
214 // to Parcel::readBlob ?
215
216 ReadableBlob blob;
217 // arg1 = metadata (blob)
218 {
219 data.readBlob(metadataSize, &blob);
220 const camera_metadata_t* tmp =
221 reinterpret_cast<const camera_metadata_t*>(blob.data());
222 size_t entry_capacity = get_camera_metadata_entry_capacity(tmp);
223 size_t data_capacity = get_camera_metadata_data_capacity(tmp);
224
225 metadata = allocate_camera_metadata(entry_capacity,
226 data_capacity);
227 copy_camera_metadata(metadata, metadataSize, tmp);
228 }
229 blob.release();
230
231 // arg2 = streaming (bool)
232 bool streaming = data.readInt32();
233
234 // return code: requestId (int32)
235 reply->writeInt32(submitRequest(metadata, streaming));
236
237 return NO_ERROR;
238 } break;
239 case CANCEL_REQUEST: {
240 CHECK_INTERFACE(IProCameraUser, data, reply);
241 int requestId = data.readInt32();
242 reply->writeInt32(cancelRequest(requestId));
243 return NO_ERROR;
244 } break;
245 case REQUEST_STREAM: {
246 CHECK_INTERFACE(IProCameraUser, data, reply);
247 int streamId = data.readInt32();
248 reply->writeInt32(requestStream(streamId));
249 return NO_ERROR;
250 } break;
251 case CANCEL_STREAM: {
252 CHECK_INTERFACE(IProCameraUser, data, reply);
253 int streamId = data.readInt32();
254 reply->writeInt32(cancelStream(streamId));
255 return NO_ERROR;
256 } break;
257 default:
258 return BBinder::onTransact(code, data, reply, flags);
259 }
260}
261
262// ----------------------------------------------------------------------------
263
264}; // namespace android