blob: 63c82cc01fcc56530a6e4b685742fdb17d27415a [file] [log] [blame]
Mathias Agopian3cf61352010-02-09 17:46:37 -08001/*
2**
3** Copyright 2008, The Android Open Source Project
4**
Ruben Brunk9efdf952015-03-18 23:11:57 -07005** 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
Mathias Agopian3cf61352010-02-09 17:46:37 -08008**
Ruben Brunk9efdf952015-03-18 23:11:57 -07009** http://www.apache.org/licenses/LICENSE-2.0
Mathias Agopian3cf61352010-02-09 17:46:37 -080010**
Ruben Brunk9efdf952015-03-18 23:11:57 -070011** 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
Mathias Agopian3cf61352010-02-09 17:46:37 -080015** limitations under the License.
16*/
17
Igor Murashkinbef3f232013-05-30 17:47:38 -070018#define LOG_TAG "BpCameraService"
19#include <utils/Log.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080020#include <utils/Errors.h>
Igor Murashkin65d14b92014-06-17 12:03:20 -070021#include <utils/String16.h>
Igor Murashkinbef3f232013-05-30 17:47:38 -070022
Mathias Agopian3cf61352010-02-09 17:46:37 -080023#include <stdint.h>
24#include <sys/types.h>
25
26#include <binder/Parcel.h>
27#include <binder/IPCThreadState.h>
28#include <binder/IServiceManager.h>
29
30#include <camera/ICameraService.h>
Igor Murashkinbfc99152013-02-27 12:55:20 -080031#include <camera/ICameraServiceListener.h>
Igor Murashkinc073ba52013-02-26 14:32:34 -080032#include <camera/ICamera.h>
33#include <camera/ICameraClient.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070034#include <camera/camera2/ICameraDeviceUser.h>
35#include <camera/camera2/ICameraDeviceCallbacks.h>
Zhijun He2b59be82013-09-25 10:14:30 -070036#include <camera/CameraMetadata.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080037#include <camera/VendorTagDescriptor.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080038
39namespace android {
40
Igor Murashkinbef3f232013-05-30 17:47:38 -070041namespace {
42
43enum {
44 EX_SECURITY = -1,
45 EX_BAD_PARCELABLE = -2,
46 EX_ILLEGAL_ARGUMENT = -3,
47 EX_NULL_POINTER = -4,
48 EX_ILLEGAL_STATE = -5,
49 EX_HAS_REPLY_HEADER = -128, // special; see below
50};
51
52static bool readExceptionCode(Parcel& reply) {
53 int32_t exceptionCode = reply.readExceptionCode();
54
55 if (exceptionCode != 0) {
56 const char* errorMsg;
57 switch(exceptionCode) {
58 case EX_SECURITY:
59 errorMsg = "Security";
60 break;
61 case EX_BAD_PARCELABLE:
62 errorMsg = "BadParcelable";
63 break;
64 case EX_NULL_POINTER:
65 errorMsg = "NullPointer";
66 break;
67 case EX_ILLEGAL_STATE:
68 errorMsg = "IllegalState";
69 break;
70 // Binder should be handling this code inside Parcel::readException
71 // but lets have a to-string here anyway just in case.
72 case EX_HAS_REPLY_HEADER:
73 errorMsg = "HasReplyHeader";
74 break;
75 default:
76 errorMsg = "Unknown";
77 }
78
79 ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
80 return true;
81 }
82
83 return false;
84}
85
86};
87
Mathias Agopian3cf61352010-02-09 17:46:37 -080088class BpCameraService: public BpInterface<ICameraService>
89{
90public:
91 BpCameraService(const sp<IBinder>& impl)
92 : BpInterface<ICameraService>(impl)
93 {
94 }
95
Chih-Chung Chang35a055b2010-05-06 16:36:58 +080096 // get number of cameras available
97 virtual int32_t getNumberOfCameras()
98 {
99 Parcel data, reply;
100 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
101 remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700102
103 if (readExceptionCode(reply)) return 0;
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800104 return reply.readInt32();
105 }
106
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800107 // get information about a camera
108 virtual status_t getCameraInfo(int cameraId,
109 struct CameraInfo* cameraInfo) {
110 Parcel data, reply;
111 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
112 data.writeInt32(cameraId);
113 remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700114
115 if (readExceptionCode(reply)) return -EPROTO;
116 status_t result = reply.readInt32();
117 if (reply.readInt32() != 0) {
118 cameraInfo->facing = reply.readInt32();
119 cameraInfo->orientation = reply.readInt32();
120 }
121 return result;
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800122 }
123
Zhijun He2b59be82013-09-25 10:14:30 -0700124 // get camera characteristics (static metadata)
125 virtual status_t getCameraCharacteristics(int cameraId,
126 CameraMetadata* cameraInfo) {
127 Parcel data, reply;
128 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
129 data.writeInt32(cameraId);
130 remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
131
132 if (readExceptionCode(reply)) return -EPROTO;
133 status_t result = reply.readInt32();
134
135 CameraMetadata out;
136 if (reply.readInt32() != 0) {
137 out.readFromParcel(&reply);
138 }
139
140 if (cameraInfo != NULL) {
141 cameraInfo->swap(out);
142 }
143
144 return result;
145 }
146
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800147 // Get enumeration and description of vendor tags for camera
148 virtual status_t getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
149 Parcel data, reply;
150 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
151 remote()->transact(BnCameraService::GET_CAMERA_VENDOR_TAG_DESCRIPTOR, data, &reply);
152
153 if (readExceptionCode(reply)) return -EPROTO;
154 status_t result = reply.readInt32();
155
156 if (reply.readInt32() != 0) {
157 sp<VendorTagDescriptor> d;
158 if (VendorTagDescriptor::createFromParcel(&reply, /*out*/d) == OK) {
159 desc = d;
160 }
161 }
162 return result;
163 }
164
Igor Murashkine7ee7632013-06-11 18:10:18 -0700165 // connect to camera service (android.hardware.Camera)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700166 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
167 const String16 &clientPackageName, int clientUid,
168 /*out*/
169 sp<ICamera>& device)
Mathias Agopian3cf61352010-02-09 17:46:37 -0800170 {
171 Parcel data, reply;
172 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800173 data.writeStrongBinder(IInterface::asBinder(cameraClient));
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800174 data.writeInt32(cameraId);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800175 data.writeString16(clientPackageName);
176 data.writeInt32(clientUid);
Mathias Agopian3cf61352010-02-09 17:46:37 -0800177 remote()->transact(BnCameraService::CONNECT, data, &reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700178
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700179 if (readExceptionCode(reply)) return -EPROTO;
180 status_t status = reply.readInt32();
181 if (reply.readInt32() != 0) {
182 device = interface_cast<ICamera>(reply.readStrongBinder());
183 }
184 return status;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800185 }
Igor Murashkin634a5152013-02-20 17:15:11 -0800186
Zhijun Heb10cdad2014-06-16 16:38:35 -0700187 // connect to camera service (android.hardware.Camera)
188 virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
189 int halVersion,
190 const String16 &clientPackageName, int clientUid,
191 /*out*/sp<ICamera>& device)
192 {
193 Parcel data, reply;
194 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800195 data.writeStrongBinder(IInterface::asBinder(cameraClient));
Zhijun Heb10cdad2014-06-16 16:38:35 -0700196 data.writeInt32(cameraId);
197 data.writeInt32(halVersion);
198 data.writeString16(clientPackageName);
199 data.writeInt32(clientUid);
200 remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
201
202 if (readExceptionCode(reply)) return -EPROTO;
203 status_t status = reply.readInt32();
204 if (reply.readInt32() != 0) {
205 device = interface_cast<ICamera>(reply.readStrongBinder());
206 }
207 return status;
208 }
209
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800210 virtual status_t setTorchMode(const String16& cameraId, bool enabled,
211 const sp<IBinder>& clientBinder)
212 {
213 Parcel data, reply;
214 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
215 data.writeString16(cameraId);
216 data.writeInt32(enabled ? 1 : 0);
217 data.writeStrongBinder(clientBinder);
218 remote()->transact(BnCameraService::SET_TORCH_MODE, data, &reply);
219
220 if (readExceptionCode(reply)) return -EPROTO;
221 return reply.readInt32();
222 }
223
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700224 // connect to camera service (android.hardware.camera2.CameraDevice)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700225 virtual status_t connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700226 const sp<ICameraDeviceCallbacks>& cameraCb,
227 int cameraId,
228 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700229 int clientUid,
230 /*out*/
231 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700232 {
233 Parcel data, reply;
234 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800235 data.writeStrongBinder(IInterface::asBinder(cameraCb));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700236 data.writeInt32(cameraId);
237 data.writeString16(clientPackageName);
238 data.writeInt32(clientUid);
239 remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
240
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700241 if (readExceptionCode(reply)) return -EPROTO;
242 status_t status = reply.readInt32();
243 if (reply.readInt32() != 0) {
244 device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
245 }
246 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700247 }
248
Igor Murashkinbfc99152013-02-27 12:55:20 -0800249 virtual status_t addListener(const sp<ICameraServiceListener>& listener)
250 {
251 Parcel data, reply;
252 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800253 data.writeStrongBinder(IInterface::asBinder(listener));
Igor Murashkinbfc99152013-02-27 12:55:20 -0800254 remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700255
256 if (readExceptionCode(reply)) return -EPROTO;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800257 return reply.readInt32();
258 }
259
260 virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
261 {
262 Parcel data, reply;
263 data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
Marco Nelissen06b46062014-11-14 07:58:25 -0800264 data.writeStrongBinder(IInterface::asBinder(listener));
Igor Murashkinbfc99152013-02-27 12:55:20 -0800265 remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700266
267 if (readExceptionCode(reply)) return -EPROTO;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800268 return reply.readInt32();
269 }
Igor Murashkin65d14b92014-06-17 12:03:20 -0700270
271 virtual status_t getLegacyParameters(int cameraId, String16* parameters) {
272 if (parameters == NULL) {
273 ALOGE("%s: parameters must not be null", __FUNCTION__);
274 return BAD_VALUE;
275 }
276
277 Parcel data, reply;
278
279 data.writeInt32(cameraId);
280 remote()->transact(BnCameraService::GET_LEGACY_PARAMETERS, data, &reply);
281 if (readExceptionCode(reply)) return -EPROTO;
282
283 status_t res = data.readInt32();
284 int32_t length = data.readInt32(); // -1 means null
285 if (length > 0) {
286 *parameters = data.readString16();
287 } else {
288 *parameters = String16();
289 }
290
291 return res;
292 }
293
294 virtual status_t supportsCameraApi(int cameraId, int apiVersion) {
295 Parcel data, reply;
296
297 data.writeInt32(cameraId);
298 data.writeInt32(apiVersion);
299 remote()->transact(BnCameraService::SUPPORTS_CAMERA_API, data, &reply);
300 if (readExceptionCode(reply)) return -EPROTO;
301
302 status_t res = data.readInt32();
303 return res;
304 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800305};
306
307IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
308
309// ----------------------------------------------------------------------
310
311status_t BnCameraService::onTransact(
312 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
313{
314 switch(code) {
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800315 case GET_NUMBER_OF_CAMERAS: {
316 CHECK_INTERFACE(ICameraService, data, reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700317 reply->writeNoException();
Chih-Chung Chang35a055b2010-05-06 16:36:58 +0800318 reply->writeInt32(getNumberOfCameras());
319 return NO_ERROR;
320 } break;
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800321 case GET_CAMERA_INFO: {
322 CHECK_INTERFACE(ICameraService, data, reply);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700323 CameraInfo cameraInfo = CameraInfo();
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800324 memset(&cameraInfo, 0, sizeof(cameraInfo));
325 status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700326 reply->writeNoException();
327 reply->writeInt32(result);
328
329 // Fake a parcelable object here
330 reply->writeInt32(1); // means the parcelable is included
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800331 reply->writeInt32(cameraInfo.facing);
332 reply->writeInt32(cameraInfo.orientation);
Chih-Chung Changddbdb352010-06-10 13:32:16 +0800333 return NO_ERROR;
334 } break;
Zhijun He2b59be82013-09-25 10:14:30 -0700335 case GET_CAMERA_CHARACTERISTICS: {
336 CHECK_INTERFACE(ICameraService, data, reply);
337 CameraMetadata info;
338 status_t result = getCameraCharacteristics(data.readInt32(), &info);
339 reply->writeNoException();
340 reply->writeInt32(result);
341
342 // out-variables are after exception and return value
343 reply->writeInt32(1); // means the parcelable is included
344 info.writeToParcel(reply);
345 return NO_ERROR;
346 } break;
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800347 case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: {
348 CHECK_INTERFACE(ICameraService, data, reply);
349 sp<VendorTagDescriptor> d;
350 status_t result = getCameraVendorTagDescriptor(d);
351 reply->writeNoException();
352 reply->writeInt32(result);
353
354 // out-variables are after exception and return value
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800355 if (d == NULL) {
356 reply->writeInt32(0);
357 } else {
Igor Murashkine1445da2014-03-17 14:00:29 -0700358 reply->writeInt32(1); // means the parcelable is included
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800359 d->writeToParcel(reply);
360 }
361 return NO_ERROR;
362 } break;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800363 case CONNECT: {
364 CHECK_INTERFACE(ICameraService, data, reply);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800365 sp<ICameraClient> cameraClient =
366 interface_cast<ICameraClient>(data.readStrongBinder());
367 int32_t cameraId = data.readInt32();
368 const String16 clientName = data.readString16();
369 int32_t clientUid = data.readInt32();
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700370 sp<ICamera> camera;
371 status_t status = connect(cameraClient, cameraId,
Igor Murashkine1445da2014-03-17 14:00:29 -0700372 clientName, clientUid, /*out*/camera);
Igor Murashkinbef3f232013-05-30 17:47:38 -0700373 reply->writeNoException();
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700374 reply->writeInt32(status);
375 if (camera != NULL) {
376 reply->writeInt32(1);
Marco Nelissen06b46062014-11-14 07:58:25 -0800377 reply->writeStrongBinder(IInterface::asBinder(camera));
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700378 } else {
379 reply->writeInt32(0);
380 }
Mathias Agopian3cf61352010-02-09 17:46:37 -0800381 return NO_ERROR;
382 } break;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700383 case CONNECT_DEVICE: {
384 CHECK_INTERFACE(ICameraService, data, reply);
385 sp<ICameraDeviceCallbacks> cameraClient =
386 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
387 int32_t cameraId = data.readInt32();
388 const String16 clientName = data.readString16();
389 int32_t clientUid = data.readInt32();
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700390 sp<ICameraDeviceUser> camera;
391 status_t status = connectDevice(cameraClient, cameraId,
Igor Murashkine1445da2014-03-17 14:00:29 -0700392 clientName, clientUid, /*out*/camera);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700393 reply->writeNoException();
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700394 reply->writeInt32(status);
395 if (camera != NULL) {
396 reply->writeInt32(1);
Marco Nelissen06b46062014-11-14 07:58:25 -0800397 reply->writeStrongBinder(IInterface::asBinder(camera));
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700398 } else {
399 reply->writeInt32(0);
400 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700401 return NO_ERROR;
402 } break;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800403 case ADD_LISTENER: {
404 CHECK_INTERFACE(ICameraService, data, reply);
405 sp<ICameraServiceListener> listener =
406 interface_cast<ICameraServiceListener>(data.readStrongBinder());
Igor Murashkinbef3f232013-05-30 17:47:38 -0700407 reply->writeNoException();
Igor Murashkinbfc99152013-02-27 12:55:20 -0800408 reply->writeInt32(addListener(listener));
409 return NO_ERROR;
410 } break;
411 case REMOVE_LISTENER: {
412 CHECK_INTERFACE(ICameraService, data, reply);
413 sp<ICameraServiceListener> listener =
414 interface_cast<ICameraServiceListener>(data.readStrongBinder());
Igor Murashkinbef3f232013-05-30 17:47:38 -0700415 reply->writeNoException();
Igor Murashkinbfc99152013-02-27 12:55:20 -0800416 reply->writeInt32(removeListener(listener));
417 return NO_ERROR;
418 } break;
Igor Murashkin65d14b92014-06-17 12:03:20 -0700419 case GET_LEGACY_PARAMETERS: {
420 CHECK_INTERFACE(ICameraService, data, reply);
421 int cameraId = data.readInt32();
422 String16 parameters;
423
424 reply->writeNoException();
425 // return value
426 reply->writeInt32(getLegacyParameters(cameraId, &parameters));
427 // out parameters
428 reply->writeInt32(1); // parameters is always available
429 reply->writeString16(parameters);
430 return NO_ERROR;
431 } break;
432 case SUPPORTS_CAMERA_API: {
433 CHECK_INTERFACE(ICameraService, data, reply);
434 int cameraId = data.readInt32();
435 int apiVersion = data.readInt32();
436
437 reply->writeNoException();
438 // return value
439 reply->writeInt32(supportsCameraApi(cameraId, apiVersion));
440 return NO_ERROR;
441 } break;
Zhijun Heb10cdad2014-06-16 16:38:35 -0700442 case CONNECT_LEGACY: {
443 CHECK_INTERFACE(ICameraService, data, reply);
444 sp<ICameraClient> cameraClient =
445 interface_cast<ICameraClient>(data.readStrongBinder());
446 int32_t cameraId = data.readInt32();
447 int32_t halVersion = data.readInt32();
448 const String16 clientName = data.readString16();
449 int32_t clientUid = data.readInt32();
450 sp<ICamera> camera;
451 status_t status = connectLegacy(cameraClient, cameraId, halVersion,
452 clientName, clientUid, /*out*/camera);
453 reply->writeNoException();
454 reply->writeInt32(status);
455 if (camera != NULL) {
456 reply->writeInt32(1);
Marco Nelissen06b46062014-11-14 07:58:25 -0800457 reply->writeStrongBinder(IInterface::asBinder(camera));
Zhijun Heb10cdad2014-06-16 16:38:35 -0700458 } else {
459 reply->writeInt32(0);
460 }
461 return NO_ERROR;
462 } break;
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800463 case SET_TORCH_MODE: {
464 CHECK_INTERFACE(ICameraService, data, reply);
465 String16 cameraId = data.readString16();
466 bool enabled = data.readInt32() != 0 ? true : false;
467 const sp<IBinder> clientBinder = data.readStrongBinder();
468 status_t status = setTorchMode(cameraId, enabled, clientBinder);
469 reply->writeNoException();
470 reply->writeInt32(status);
471 return NO_ERROR;
472 } break;
Mathias Agopian3cf61352010-02-09 17:46:37 -0800473 default:
474 return BBinder::onTransact(code, data, reply, flags);
475 }
476}
477
478// ----------------------------------------------------------------------------
479
480}; // namespace android