1 /*
2 **
3 ** Copyright 2008, 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_TAG "BpCameraService"
19 #include <utils/Log.h>
20
21 #include <stdint.h>
22 #include <sys/types.h>
23
24 #include <binder/Parcel.h>
25 #include <binder/IPCThreadState.h>
26 #include <binder/IServiceManager.h>
27
28 #include <camera/ICameraService.h>
29 #include <camera/ICameraServiceListener.h>
30 #include <camera/IProCameraUser.h>
31 #include <camera/IProCameraCallbacks.h>
32 #include <camera/ICamera.h>
33 #include <camera/ICameraClient.h>
34 #include <camera/camera2/ICameraDeviceUser.h>
35 #include <camera/camera2/ICameraDeviceCallbacks.h>
36 #include <camera/CameraMetadata.h>
37
38 namespace android {
39
40 namespace {
41
42 enum {
43 EX_SECURITY = -1,
44 EX_BAD_PARCELABLE = -2,
45 EX_ILLEGAL_ARGUMENT = -3,
46 EX_NULL_POINTER = -4,
47 EX_ILLEGAL_STATE = -5,
48 EX_HAS_REPLY_HEADER = -128, // special; see below
49 };
50
readExceptionCode(Parcel & reply)51 static bool readExceptionCode(Parcel& reply) {
52 int32_t exceptionCode = reply.readExceptionCode();
53
54 if (exceptionCode != 0) {
55 const char* errorMsg;
56 switch(exceptionCode) {
57 case EX_SECURITY:
58 errorMsg = "Security";
59 break;
60 case EX_BAD_PARCELABLE:
61 errorMsg = "BadParcelable";
62 break;
63 case EX_NULL_POINTER:
64 errorMsg = "NullPointer";
65 break;
66 case EX_ILLEGAL_STATE:
67 errorMsg = "IllegalState";
68 break;
69 // Binder should be handling this code inside Parcel::readException
70 // but lets have a to-string here anyway just in case.
71 case EX_HAS_REPLY_HEADER:
72 errorMsg = "HasReplyHeader";
73 break;
74 default:
75 errorMsg = "Unknown";
76 }
77
78 ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
79 return true;
80 }
81
82 return false;
83 }
84
85 };
86
87 class BpCameraService: public BpInterface<ICameraService>
88 {
89 public:
BpCameraService(const sp<IBinder> & impl)90 BpCameraService(const sp<IBinder>& impl)
91 : BpInterface<ICameraService>(impl)
92 {
93 }
94
95 // get number of cameras available
getNumberOfCameras()96 virtual int32_t getNumberOfCameras()
97 {
98 Parcel data, reply;
99 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
100 remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
101
102 if (readExceptionCode(reply)) return 0;
103 return reply.readInt32();
104 }
105
106 // get information about a camera
getCameraInfo(int cameraId,struct CameraInfo * cameraInfo)107 virtual status_t getCameraInfo(int cameraId,
108 struct CameraInfo* cameraInfo) {
109 Parcel data, reply;
110 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
111 data.writeInt32(cameraId);
112 remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
113
114 if (readExceptionCode(reply)) return -EPROTO;
115 status_t result = reply.readInt32();
116 if (reply.readInt32() != 0) {
117 cameraInfo->facing = reply.readInt32();
118 cameraInfo->orientation = reply.readInt32();
119 }
120 return result;
121 }
122
123 // get camera characteristics (static metadata)
getCameraCharacteristics(int cameraId,CameraMetadata * cameraInfo)124 virtual status_t getCameraCharacteristics(int cameraId,
125 CameraMetadata* cameraInfo) {
126 Parcel data, reply;
127 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
128 data.writeInt32(cameraId);
129 remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
130
131 if (readExceptionCode(reply)) return -EPROTO;
132 status_t result = reply.readInt32();
133
134 CameraMetadata out;
135 if (reply.readInt32() != 0) {
136 out.readFromParcel(&reply);
137 }
138
139 if (cameraInfo != NULL) {
140 cameraInfo->swap(out);
141 }
142
143 return result;
144 }
145
146 // connect to camera service (android.hardware.Camera)
connect(const sp<ICameraClient> & cameraClient,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICamera> & device)147 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
148 const String16 &clientPackageName, int clientUid,
149 /*out*/
150 sp<ICamera>& device)
151 {
152 Parcel data, reply;
153 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
154 data.writeStrongBinder(cameraClient->asBinder());
155 data.writeInt32(cameraId);
156 data.writeString16(clientPackageName);
157 data.writeInt32(clientUid);
158 remote()->transact(BnCameraService::CONNECT, data, &reply);
159
160 if (readExceptionCode(reply)) return -EPROTO;
161 status_t status = reply.readInt32();
162 if (reply.readInt32() != 0) {
163 device = interface_cast<ICamera>(reply.readStrongBinder());
164 }
165 return status;
166 }
167
168 // connect to camera service (pro client)
connectPro(const sp<IProCameraCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<IProCameraUser> & device)169 virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
170 const String16 &clientPackageName, int clientUid,
171 /*out*/
172 sp<IProCameraUser>& device)
173 {
174 Parcel data, reply;
175 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
176 data.writeStrongBinder(cameraCb->asBinder());
177 data.writeInt32(cameraId);
178 data.writeString16(clientPackageName);
179 data.writeInt32(clientUid);
180 remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
181
182 if (readExceptionCode(reply)) return -EPROTO;
183 status_t status = reply.readInt32();
184 if (reply.readInt32() != 0) {
185 device = interface_cast<IProCameraUser>(reply.readStrongBinder());
186 }
187 return status;
188 }
189
190 // connect to camera service (android.hardware.camera2.CameraDevice)
connectDevice(const sp<ICameraDeviceCallbacks> & cameraCb,int cameraId,const String16 & clientPackageName,int clientUid,sp<ICameraDeviceUser> & device)191 virtual status_t connectDevice(
192 const sp<ICameraDeviceCallbacks>& cameraCb,
193 int cameraId,
194 const String16& clientPackageName,
195 int clientUid,
196 /*out*/
197 sp<ICameraDeviceUser>& device)
198 {
199 Parcel data, reply;
200 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
201 data.writeStrongBinder(cameraCb->asBinder());
202 data.writeInt32(cameraId);
203 data.writeString16(clientPackageName);
204 data.writeInt32(clientUid);
205 remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
206
207 if (readExceptionCode(reply)) return -EPROTO;
208 status_t status = reply.readInt32();
209 if (reply.readInt32() != 0) {
210 device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
211 }
212 return status;
213 }
214
addListener(const sp<ICameraServiceListener> & listener)215 virtual status_t addListener(const sp<ICameraServiceListener>& listener)
216 {
217 Parcel data, reply;
218 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
219 data.writeStrongBinder(listener->asBinder());
220 remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
221
222 if (readExceptionCode(reply)) return -EPROTO;
223 return reply.readInt32();
224 }
225
removeListener(const sp<ICameraServiceListener> & listener)226 virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
227 {
228 Parcel data, reply;
229 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
230 data.writeStrongBinder(listener->asBinder());
231 remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
232
233 if (readExceptionCode(reply)) return -EPROTO;
234 return reply.readInt32();
235 }
236 };
237
238 IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
239
240 // ----------------------------------------------------------------------
241
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)242 status_t BnCameraService::onTransact(
243 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
244 {
245 switch(code) {
246 case GET_NUMBER_OF_CAMERAS: {
247 CHECK_INTERFACE(ICameraService, data, reply);
248 reply->writeNoException();
249 reply->writeInt32(getNumberOfCameras());
250 return NO_ERROR;
251 } break;
252 case GET_CAMERA_INFO: {
253 CHECK_INTERFACE(ICameraService, data, reply);
254 CameraInfo cameraInfo = CameraInfo();
255 memset(&cameraInfo, 0, sizeof(cameraInfo));
256 status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
257 reply->writeNoException();
258 reply->writeInt32(result);
259
260 // Fake a parcelable object here
261 reply->writeInt32(1); // means the parcelable is included
262 reply->writeInt32(cameraInfo.facing);
263 reply->writeInt32(cameraInfo.orientation);
264 return NO_ERROR;
265 } break;
266 case GET_CAMERA_CHARACTERISTICS: {
267 CHECK_INTERFACE(ICameraService, data, reply);
268 CameraMetadata info;
269 status_t result = getCameraCharacteristics(data.readInt32(), &info);
270 reply->writeNoException();
271 reply->writeInt32(result);
272
273 // out-variables are after exception and return value
274 reply->writeInt32(1); // means the parcelable is included
275 info.writeToParcel(reply);
276 return NO_ERROR;
277 } break;
278 case CONNECT: {
279 CHECK_INTERFACE(ICameraService, data, reply);
280 sp<ICameraClient> cameraClient =
281 interface_cast<ICameraClient>(data.readStrongBinder());
282 int32_t cameraId = data.readInt32();
283 const String16 clientName = data.readString16();
284 int32_t clientUid = data.readInt32();
285 sp<ICamera> camera;
286 status_t status = connect(cameraClient, cameraId,
287 clientName, clientUid, /*out*/ camera);
288 reply->writeNoException();
289 reply->writeInt32(status);
290 if (camera != NULL) {
291 reply->writeInt32(1);
292 reply->writeStrongBinder(camera->asBinder());
293 } else {
294 reply->writeInt32(0);
295 }
296 return NO_ERROR;
297 } break;
298 case CONNECT_PRO: {
299 CHECK_INTERFACE(ICameraService, data, reply);
300 sp<IProCameraCallbacks> cameraClient =
301 interface_cast<IProCameraCallbacks>(data.readStrongBinder());
302 int32_t cameraId = data.readInt32();
303 const String16 clientName = data.readString16();
304 int32_t clientUid = data.readInt32();
305 sp<IProCameraUser> camera;
306 status_t status = connectPro(cameraClient, cameraId,
307 clientName, clientUid, /*out*/ camera);
308 reply->writeNoException();
309 reply->writeInt32(status);
310 if (camera != NULL) {
311 reply->writeInt32(1);
312 reply->writeStrongBinder(camera->asBinder());
313 } else {
314 reply->writeInt32(0);
315 }
316 return NO_ERROR;
317 } break;
318 case CONNECT_DEVICE: {
319 CHECK_INTERFACE(ICameraService, data, reply);
320 sp<ICameraDeviceCallbacks> cameraClient =
321 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
322 int32_t cameraId = data.readInt32();
323 const String16 clientName = data.readString16();
324 int32_t clientUid = data.readInt32();
325 sp<ICameraDeviceUser> camera;
326 status_t status = connectDevice(cameraClient, cameraId,
327 clientName, clientUid, /*out*/ camera);
328 reply->writeNoException();
329 reply->writeInt32(status);
330 if (camera != NULL) {
331 reply->writeInt32(1);
332 reply->writeStrongBinder(camera->asBinder());
333 } else {
334 reply->writeInt32(0);
335 }
336 return NO_ERROR;
337 } break;
338 case ADD_LISTENER: {
339 CHECK_INTERFACE(ICameraService, data, reply);
340 sp<ICameraServiceListener> listener =
341 interface_cast<ICameraServiceListener>(data.readStrongBinder());
342 reply->writeNoException();
343 reply->writeInt32(addListener(listener));
344 return NO_ERROR;
345 } break;
346 case REMOVE_LISTENER: {
347 CHECK_INTERFACE(ICameraService, data, reply);
348 sp<ICameraServiceListener> listener =
349 interface_cast<ICameraServiceListener>(data.readStrongBinder());
350 reply->writeNoException();
351 reply->writeInt32(removeListener(listener));
352 return NO_ERROR;
353 } break;
354 default:
355 return BBinder::onTransact(code, data, reply, flags);
356 }
357 }
358
359 // ----------------------------------------------------------------------------
360
361 }; // namespace android
362