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 #include <arpa/inet.h> 19 #include <stdint.h> 20 #include <sys/types.h> 21 22 #include <binder/Parcel.h> 23 24 #include <media/AudioResamplerPublic.h> 25 #include <media/AVSyncSettings.h> 26 27 #include <media/IDataSource.h> 28 #include <media/IMediaHTTPService.h> 29 #include <media/IMediaPlayer.h> 30 #include <media/IStreamSource.h> 31 32 #include <gui/IGraphicBufferProducer.h> 33 #include <utils/String8.h> 34 35 namespace android { 36 37 enum { 38 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, 39 SET_DATA_SOURCE_URL, 40 SET_DATA_SOURCE_FD, 41 SET_DATA_SOURCE_STREAM, 42 SET_DATA_SOURCE_CALLBACK, 43 PREPARE_ASYNC, 44 START, 45 STOP, 46 IS_PLAYING, 47 SET_PLAYBACK_SETTINGS, 48 GET_PLAYBACK_SETTINGS, 49 SET_SYNC_SETTINGS, 50 GET_SYNC_SETTINGS, 51 PAUSE, 52 SEEK_TO, 53 GET_CURRENT_POSITION, 54 GET_DURATION, 55 RESET, 56 SET_AUDIO_STREAM_TYPE, 57 SET_LOOPING, 58 SET_VOLUME, 59 INVOKE, 60 SET_METADATA_FILTER, 61 GET_METADATA, 62 SET_AUX_EFFECT_SEND_LEVEL, 63 ATTACH_AUX_EFFECT, 64 SET_VIDEO_SURFACETEXTURE, 65 SET_PARAMETER, 66 GET_PARAMETER, 67 SET_RETRANSMIT_ENDPOINT, 68 GET_RETRANSMIT_ENDPOINT, 69 SET_NEXT_PLAYER, 70 }; 71 72 class BpMediaPlayer: public BpInterface<IMediaPlayer> 73 { 74 public: 75 BpMediaPlayer(const sp<IBinder>& impl) 76 : BpInterface<IMediaPlayer>(impl) 77 { 78 } 79 80 // disconnect from media player service 81 void disconnect() 82 { 83 Parcel data, reply; 84 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 85 remote()->transact(DISCONNECT, data, &reply); 86 } 87 88 status_t setDataSource( 89 const sp<IMediaHTTPService> &httpService, 90 const char* url, 91 const KeyedVector<String8, String8>* headers) 92 { 93 Parcel data, reply; 94 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 95 data.writeInt32(httpService != NULL); 96 if (httpService != NULL) { 97 data.writeStrongBinder(IInterface::asBinder(httpService)); 98 } 99 data.writeCString(url); 100 if (headers == NULL) { 101 data.writeInt32(0); 102 } else { 103 // serialize the headers 104 data.writeInt32(headers->size()); 105 for (size_t i = 0; i < headers->size(); ++i) { 106 data.writeString8(headers->keyAt(i)); 107 data.writeString8(headers->valueAt(i)); 108 } 109 } 110 remote()->transact(SET_DATA_SOURCE_URL, data, &reply); 111 return reply.readInt32(); 112 } 113 114 status_t setDataSource(int fd, int64_t offset, int64_t length) { 115 Parcel data, reply; 116 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 117 data.writeFileDescriptor(fd); 118 data.writeInt64(offset); 119 data.writeInt64(length); 120 remote()->transact(SET_DATA_SOURCE_FD, data, &reply); 121 return reply.readInt32(); 122 } 123 124 status_t setDataSource(const sp<IStreamSource> &source) { 125 Parcel data, reply; 126 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 127 data.writeStrongBinder(IInterface::asBinder(source)); 128 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply); 129 return reply.readInt32(); 130 } 131 132 status_t setDataSource(const sp<IDataSource> &source) { 133 Parcel data, reply; 134 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 135 data.writeStrongBinder(IInterface::asBinder(source)); 136 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply); 137 return reply.readInt32(); 138 } 139 140 // pass the buffered IGraphicBufferProducer to the media player service 141 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer) 142 { 143 Parcel data, reply; 144 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 145 sp<IBinder> b(IInterface::asBinder(bufferProducer)); 146 data.writeStrongBinder(b); 147 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply); 148 return reply.readInt32(); 149 } 150 151 status_t prepareAsync() 152 { 153 Parcel data, reply; 154 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 155 remote()->transact(PREPARE_ASYNC, data, &reply); 156 return reply.readInt32(); 157 } 158 159 status_t start() 160 { 161 Parcel data, reply; 162 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 163 remote()->transact(START, data, &reply); 164 return reply.readInt32(); 165 } 166 167 status_t stop() 168 { 169 Parcel data, reply; 170 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 171 remote()->transact(STOP, data, &reply); 172 return reply.readInt32(); 173 } 174 175 status_t isPlaying(bool* state) 176 { 177 Parcel data, reply; 178 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 179 remote()->transact(IS_PLAYING, data, &reply); 180 *state = reply.readInt32(); 181 return reply.readInt32(); 182 } 183 184 status_t setPlaybackSettings(const AudioPlaybackRate& rate) 185 { 186 Parcel data, reply; 187 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 188 data.writeFloat(rate.mSpeed); 189 data.writeFloat(rate.mPitch); 190 data.writeInt32((int32_t)rate.mFallbackMode); 191 data.writeInt32((int32_t)rate.mStretchMode); 192 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply); 193 return reply.readInt32(); 194 } 195 196 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) 197 { 198 Parcel data, reply; 199 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 200 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply); 201 status_t err = reply.readInt32(); 202 if (err == OK) { 203 *rate = AUDIO_PLAYBACK_RATE_DEFAULT; 204 rate->mSpeed = reply.readFloat(); 205 rate->mPitch = reply.readFloat(); 206 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32(); 207 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32(); 208 } 209 return err; 210 } 211 212 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) 213 { 214 Parcel data, reply; 215 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 216 data.writeInt32((int32_t)sync.mSource); 217 data.writeInt32((int32_t)sync.mAudioAdjustMode); 218 data.writeFloat(sync.mTolerance); 219 data.writeFloat(videoFpsHint); 220 remote()->transact(SET_SYNC_SETTINGS, data, &reply); 221 return reply.readInt32(); 222 } 223 224 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) 225 { 226 Parcel data, reply; 227 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 228 remote()->transact(GET_SYNC_SETTINGS, data, &reply); 229 status_t err = reply.readInt32(); 230 if (err == OK) { 231 AVSyncSettings settings; 232 settings.mSource = (AVSyncSource)reply.readInt32(); 233 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32(); 234 settings.mTolerance = reply.readFloat(); 235 *sync = settings; 236 *videoFps = reply.readFloat(); 237 } 238 return err; 239 } 240 241 status_t pause() 242 { 243 Parcel data, reply; 244 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 245 remote()->transact(PAUSE, data, &reply); 246 return reply.readInt32(); 247 } 248 249 status_t seekTo(int msec) 250 { 251 Parcel data, reply; 252 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 253 data.writeInt32(msec); 254 remote()->transact(SEEK_TO, data, &reply); 255 return reply.readInt32(); 256 } 257 258 status_t getCurrentPosition(int* msec) 259 { 260 Parcel data, reply; 261 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 262 remote()->transact(GET_CURRENT_POSITION, data, &reply); 263 *msec = reply.readInt32(); 264 return reply.readInt32(); 265 } 266 267 status_t getDuration(int* msec) 268 { 269 Parcel data, reply; 270 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 271 remote()->transact(GET_DURATION, data, &reply); 272 *msec = reply.readInt32(); 273 return reply.readInt32(); 274 } 275 276 status_t reset() 277 { 278 Parcel data, reply; 279 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 280 remote()->transact(RESET, data, &reply); 281 return reply.readInt32(); 282 } 283 284 status_t setAudioStreamType(audio_stream_type_t stream) 285 { 286 Parcel data, reply; 287 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 288 data.writeInt32((int32_t) stream); 289 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply); 290 return reply.readInt32(); 291 } 292 293 status_t setLooping(int loop) 294 { 295 Parcel data, reply; 296 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 297 data.writeInt32(loop); 298 remote()->transact(SET_LOOPING, data, &reply); 299 return reply.readInt32(); 300 } 301 302 status_t setVolume(float leftVolume, float rightVolume) 303 { 304 Parcel data, reply; 305 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 306 data.writeFloat(leftVolume); 307 data.writeFloat(rightVolume); 308 remote()->transact(SET_VOLUME, data, &reply); 309 return reply.readInt32(); 310 } 311 312 status_t invoke(const Parcel& request, Parcel *reply) 313 { 314 // Avoid doing any extra copy. The interface descriptor should 315 // have been set by MediaPlayer.java. 316 return remote()->transact(INVOKE, request, reply); 317 } 318 319 status_t setMetadataFilter(const Parcel& request) 320 { 321 Parcel reply; 322 // Avoid doing any extra copy of the request. The interface 323 // descriptor should have been set by MediaPlayer.java. 324 remote()->transact(SET_METADATA_FILTER, request, &reply); 325 return reply.readInt32(); 326 } 327 328 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply) 329 { 330 Parcel request; 331 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 332 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here. 333 request.writeInt32(update_only); 334 request.writeInt32(apply_filter); 335 remote()->transact(GET_METADATA, request, reply); 336 return reply->readInt32(); 337 } 338 339 status_t setAuxEffectSendLevel(float level) 340 { 341 Parcel data, reply; 342 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 343 data.writeFloat(level); 344 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply); 345 return reply.readInt32(); 346 } 347 348 status_t attachAuxEffect(int effectId) 349 { 350 Parcel data, reply; 351 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 352 data.writeInt32(effectId); 353 remote()->transact(ATTACH_AUX_EFFECT, data, &reply); 354 return reply.readInt32(); 355 } 356 357 status_t setParameter(int key, const Parcel& request) 358 { 359 Parcel data, reply; 360 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 361 data.writeInt32(key); 362 if (request.dataSize() > 0) { 363 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize()); 364 } 365 remote()->transact(SET_PARAMETER, data, &reply); 366 return reply.readInt32(); 367 } 368 369 status_t getParameter(int key, Parcel *reply) 370 { 371 Parcel data; 372 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 373 data.writeInt32(key); 374 return remote()->transact(GET_PARAMETER, data, reply); 375 } 376 377 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) 378 { 379 Parcel data, reply; 380 status_t err; 381 382 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 383 if (NULL != endpoint) { 384 data.writeInt32(sizeof(*endpoint)); 385 data.write(endpoint, sizeof(*endpoint)); 386 } else { 387 data.writeInt32(0); 388 } 389 390 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply); 391 if (OK != err) { 392 return err; 393 } 394 return reply.readInt32(); 395 } 396 397 status_t setNextPlayer(const sp<IMediaPlayer>& player) { 398 Parcel data, reply; 399 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 400 sp<IBinder> b(IInterface::asBinder(player)); 401 data.writeStrongBinder(b); 402 remote()->transact(SET_NEXT_PLAYER, data, &reply); 403 return reply.readInt32(); 404 } 405 406 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) 407 { 408 Parcel data, reply; 409 status_t err; 410 411 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 412 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply); 413 414 if ((OK != err) || (OK != (err = reply.readInt32()))) { 415 return err; 416 } 417 418 data.read(endpoint, sizeof(*endpoint)); 419 420 return err; 421 } 422 }; 423 424 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); 425 426 // ---------------------------------------------------------------------- 427 428 status_t BnMediaPlayer::onTransact( 429 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 430 { 431 switch (code) { 432 case DISCONNECT: { 433 CHECK_INTERFACE(IMediaPlayer, data, reply); 434 disconnect(); 435 return NO_ERROR; 436 } break; 437 case SET_DATA_SOURCE_URL: { 438 CHECK_INTERFACE(IMediaPlayer, data, reply); 439 440 sp<IMediaHTTPService> httpService; 441 if (data.readInt32()) { 442 httpService = 443 interface_cast<IMediaHTTPService>(data.readStrongBinder()); 444 } 445 446 const char* url = data.readCString(); 447 KeyedVector<String8, String8> headers; 448 int32_t numHeaders = data.readInt32(); 449 for (int i = 0; i < numHeaders; ++i) { 450 String8 key = data.readString8(); 451 String8 value = data.readString8(); 452 headers.add(key, value); 453 } 454 reply->writeInt32(setDataSource( 455 httpService, url, numHeaders > 0 ? &headers : NULL)); 456 return NO_ERROR; 457 } break; 458 case SET_DATA_SOURCE_FD: { 459 CHECK_INTERFACE(IMediaPlayer, data, reply); 460 int fd = data.readFileDescriptor(); 461 int64_t offset = data.readInt64(); 462 int64_t length = data.readInt64(); 463 reply->writeInt32(setDataSource(fd, offset, length)); 464 return NO_ERROR; 465 } 466 case SET_DATA_SOURCE_STREAM: { 467 CHECK_INTERFACE(IMediaPlayer, data, reply); 468 sp<IStreamSource> source = 469 interface_cast<IStreamSource>(data.readStrongBinder()); 470 reply->writeInt32(setDataSource(source)); 471 return NO_ERROR; 472 } 473 case SET_DATA_SOURCE_CALLBACK: { 474 CHECK_INTERFACE(IMediaPlayer, data, reply); 475 sp<IDataSource> source = 476 interface_cast<IDataSource>(data.readStrongBinder()); 477 reply->writeInt32(setDataSource(source)); 478 return NO_ERROR; 479 } 480 case SET_VIDEO_SURFACETEXTURE: { 481 CHECK_INTERFACE(IMediaPlayer, data, reply); 482 sp<IGraphicBufferProducer> bufferProducer = 483 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 484 reply->writeInt32(setVideoSurfaceTexture(bufferProducer)); 485 return NO_ERROR; 486 } break; 487 case PREPARE_ASYNC: { 488 CHECK_INTERFACE(IMediaPlayer, data, reply); 489 reply->writeInt32(prepareAsync()); 490 return NO_ERROR; 491 } break; 492 case START: { 493 CHECK_INTERFACE(IMediaPlayer, data, reply); 494 reply->writeInt32(start()); 495 return NO_ERROR; 496 } break; 497 case STOP: { 498 CHECK_INTERFACE(IMediaPlayer, data, reply); 499 reply->writeInt32(stop()); 500 return NO_ERROR; 501 } break; 502 case IS_PLAYING: { 503 CHECK_INTERFACE(IMediaPlayer, data, reply); 504 bool state; 505 status_t ret = isPlaying(&state); 506 reply->writeInt32(state); 507 reply->writeInt32(ret); 508 return NO_ERROR; 509 } break; 510 case SET_PLAYBACK_SETTINGS: { 511 CHECK_INTERFACE(IMediaPlayer, data, reply); 512 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; 513 rate.mSpeed = data.readFloat(); 514 rate.mPitch = data.readFloat(); 515 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32(); 516 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32(); 517 reply->writeInt32(setPlaybackSettings(rate)); 518 return NO_ERROR; 519 } break; 520 case GET_PLAYBACK_SETTINGS: { 521 CHECK_INTERFACE(IMediaPlayer, data, reply); 522 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; 523 status_t err = getPlaybackSettings(&rate); 524 reply->writeInt32(err); 525 if (err == OK) { 526 reply->writeFloat(rate.mSpeed); 527 reply->writeFloat(rate.mPitch); 528 reply->writeInt32((int32_t)rate.mFallbackMode); 529 reply->writeInt32((int32_t)rate.mStretchMode); 530 } 531 return NO_ERROR; 532 } break; 533 case SET_SYNC_SETTINGS: { 534 CHECK_INTERFACE(IMediaPlayer, data, reply); 535 AVSyncSettings sync; 536 sync.mSource = (AVSyncSource)data.readInt32(); 537 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32(); 538 sync.mTolerance = data.readFloat(); 539 float videoFpsHint = data.readFloat(); 540 reply->writeInt32(setSyncSettings(sync, videoFpsHint)); 541 return NO_ERROR; 542 } break; 543 case GET_SYNC_SETTINGS: { 544 CHECK_INTERFACE(IMediaPlayer, data, reply); 545 AVSyncSettings sync; 546 float videoFps; 547 status_t err = getSyncSettings(&sync, &videoFps); 548 reply->writeInt32(err); 549 if (err == OK) { 550 reply->writeInt32((int32_t)sync.mSource); 551 reply->writeInt32((int32_t)sync.mAudioAdjustMode); 552 reply->writeFloat(sync.mTolerance); 553 reply->writeFloat(videoFps); 554 } 555 return NO_ERROR; 556 } break; 557 case PAUSE: { 558 CHECK_INTERFACE(IMediaPlayer, data, reply); 559 reply->writeInt32(pause()); 560 return NO_ERROR; 561 } break; 562 case SEEK_TO: { 563 CHECK_INTERFACE(IMediaPlayer, data, reply); 564 reply->writeInt32(seekTo(data.readInt32())); 565 return NO_ERROR; 566 } break; 567 case GET_CURRENT_POSITION: { 568 CHECK_INTERFACE(IMediaPlayer, data, reply); 569 int msec; 570 status_t ret = getCurrentPosition(&msec); 571 reply->writeInt32(msec); 572 reply->writeInt32(ret); 573 return NO_ERROR; 574 } break; 575 case GET_DURATION: { 576 CHECK_INTERFACE(IMediaPlayer, data, reply); 577 int msec; 578 status_t ret = getDuration(&msec); 579 reply->writeInt32(msec); 580 reply->writeInt32(ret); 581 return NO_ERROR; 582 } break; 583 case RESET: { 584 CHECK_INTERFACE(IMediaPlayer, data, reply); 585 reply->writeInt32(reset()); 586 return NO_ERROR; 587 } break; 588 case SET_AUDIO_STREAM_TYPE: { 589 CHECK_INTERFACE(IMediaPlayer, data, reply); 590 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32())); 591 return NO_ERROR; 592 } break; 593 case SET_LOOPING: { 594 CHECK_INTERFACE(IMediaPlayer, data, reply); 595 reply->writeInt32(setLooping(data.readInt32())); 596 return NO_ERROR; 597 } break; 598 case SET_VOLUME: { 599 CHECK_INTERFACE(IMediaPlayer, data, reply); 600 float leftVolume = data.readFloat(); 601 float rightVolume = data.readFloat(); 602 reply->writeInt32(setVolume(leftVolume, rightVolume)); 603 return NO_ERROR; 604 } break; 605 case INVOKE: { 606 CHECK_INTERFACE(IMediaPlayer, data, reply); 607 status_t result = invoke(data, reply); 608 return result; 609 } break; 610 case SET_METADATA_FILTER: { 611 CHECK_INTERFACE(IMediaPlayer, data, reply); 612 reply->writeInt32(setMetadataFilter(data)); 613 return NO_ERROR; 614 } break; 615 case GET_METADATA: { 616 CHECK_INTERFACE(IMediaPlayer, data, reply); 617 bool update_only = static_cast<bool>(data.readInt32()); 618 bool apply_filter = static_cast<bool>(data.readInt32()); 619 const status_t retcode = getMetadata(update_only, apply_filter, reply); 620 reply->setDataPosition(0); 621 reply->writeInt32(retcode); 622 reply->setDataPosition(0); 623 return NO_ERROR; 624 } break; 625 case SET_AUX_EFFECT_SEND_LEVEL: { 626 CHECK_INTERFACE(IMediaPlayer, data, reply); 627 reply->writeInt32(setAuxEffectSendLevel(data.readFloat())); 628 return NO_ERROR; 629 } break; 630 case ATTACH_AUX_EFFECT: { 631 CHECK_INTERFACE(IMediaPlayer, data, reply); 632 reply->writeInt32(attachAuxEffect(data.readInt32())); 633 return NO_ERROR; 634 } break; 635 case SET_PARAMETER: { 636 CHECK_INTERFACE(IMediaPlayer, data, reply); 637 int key = data.readInt32(); 638 639 Parcel request; 640 if (data.dataAvail() > 0) { 641 request.appendFrom( 642 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); 643 } 644 request.setDataPosition(0); 645 reply->writeInt32(setParameter(key, request)); 646 return NO_ERROR; 647 } break; 648 case GET_PARAMETER: { 649 CHECK_INTERFACE(IMediaPlayer, data, reply); 650 return getParameter(data.readInt32(), reply); 651 } break; 652 case SET_RETRANSMIT_ENDPOINT: { 653 CHECK_INTERFACE(IMediaPlayer, data, reply); 654 655 struct sockaddr_in endpoint; 656 memset(&endpoint, 0, sizeof(endpoint)); 657 int amt = data.readInt32(); 658 if (amt == sizeof(endpoint)) { 659 data.read(&endpoint, sizeof(struct sockaddr_in)); 660 reply->writeInt32(setRetransmitEndpoint(&endpoint)); 661 } else { 662 reply->writeInt32(setRetransmitEndpoint(NULL)); 663 } 664 665 return NO_ERROR; 666 } break; 667 case GET_RETRANSMIT_ENDPOINT: { 668 CHECK_INTERFACE(IMediaPlayer, data, reply); 669 670 struct sockaddr_in endpoint; 671 memset(&endpoint, 0, sizeof(endpoint)); 672 status_t res = getRetransmitEndpoint(&endpoint); 673 674 reply->writeInt32(res); 675 reply->write(&endpoint, sizeof(endpoint)); 676 677 return NO_ERROR; 678 } break; 679 case SET_NEXT_PLAYER: { 680 CHECK_INTERFACE(IMediaPlayer, data, reply); 681 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder()))); 682 683 return NO_ERROR; 684 } break; 685 default: 686 return BBinder::onTransact(code, data, reply, flags); 687 } 688 } 689 690 // ---------------------------------------------------------------------------- 691 692 } // namespace android 693