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#include <media/BufferingSettings.h> 27 28#include <media/IDataSource.h> 29#include <media/IMediaHTTPService.h> 30#include <media/IMediaPlayer.h> 31#include <media/IStreamSource.h> 32 33#include <gui/IGraphicBufferProducer.h> 34#include <utils/String8.h> 35 36namespace android { 37 38enum { 39 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, 40 SET_DATA_SOURCE_URL, 41 SET_DATA_SOURCE_FD, 42 SET_DATA_SOURCE_STREAM, 43 SET_DATA_SOURCE_CALLBACK, 44 SET_BUFFERING_SETTINGS, 45 GET_DEFAULT_BUFFERING_SETTINGS, 46 PREPARE_ASYNC, 47 START, 48 STOP, 49 IS_PLAYING, 50 SET_PLAYBACK_SETTINGS, 51 GET_PLAYBACK_SETTINGS, 52 SET_SYNC_SETTINGS, 53 GET_SYNC_SETTINGS, 54 PAUSE, 55 SEEK_TO, 56 GET_CURRENT_POSITION, 57 GET_DURATION, 58 RESET, 59 SET_AUDIO_STREAM_TYPE, 60 SET_LOOPING, 61 SET_VOLUME, 62 INVOKE, 63 SET_METADATA_FILTER, 64 GET_METADATA, 65 SET_AUX_EFFECT_SEND_LEVEL, 66 ATTACH_AUX_EFFECT, 67 SET_VIDEO_SURFACETEXTURE, 68 SET_PARAMETER, 69 GET_PARAMETER, 70 SET_RETRANSMIT_ENDPOINT, 71 GET_RETRANSMIT_ENDPOINT, 72 SET_NEXT_PLAYER, 73 APPLY_VOLUME_SHAPER, 74 GET_VOLUME_SHAPER_STATE, 75 // Modular DRM 76 PREPARE_DRM, 77 RELEASE_DRM, 78}; 79 80// ModDrm helpers 81static void readVector(const Parcel& reply, Vector<uint8_t>& vector) { 82 uint32_t size = reply.readUint32(); 83 vector.insertAt((size_t)0, size); 84 reply.read(vector.editArray(), size); 85} 86 87static void writeVector(Parcel& data, Vector<uint8_t> const& vector) { 88 data.writeUint32(vector.size()); 89 data.write(vector.array(), vector.size()); 90} 91 92class BpMediaPlayer: public BpInterface<IMediaPlayer> 93{ 94public: 95 explicit BpMediaPlayer(const sp<IBinder>& impl) 96 : BpInterface<IMediaPlayer>(impl) 97 { 98 } 99 100 // disconnect from media player service 101 void disconnect() 102 { 103 Parcel data, reply; 104 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 105 remote()->transact(DISCONNECT, data, &reply); 106 } 107 108 status_t setDataSource( 109 const sp<IMediaHTTPService> &httpService, 110 const char* url, 111 const KeyedVector<String8, String8>* headers) 112 { 113 Parcel data, reply; 114 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 115 data.writeInt32(httpService != NULL); 116 if (httpService != NULL) { 117 data.writeStrongBinder(IInterface::asBinder(httpService)); 118 } 119 data.writeCString(url); 120 if (headers == NULL) { 121 data.writeInt32(0); 122 } else { 123 // serialize the headers 124 data.writeInt32(headers->size()); 125 for (size_t i = 0; i < headers->size(); ++i) { 126 data.writeString8(headers->keyAt(i)); 127 data.writeString8(headers->valueAt(i)); 128 } 129 } 130 remote()->transact(SET_DATA_SOURCE_URL, data, &reply); 131 return reply.readInt32(); 132 } 133 134 status_t setDataSource(int fd, int64_t offset, int64_t length) { 135 Parcel data, reply; 136 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 137 data.writeFileDescriptor(fd); 138 data.writeInt64(offset); 139 data.writeInt64(length); 140 remote()->transact(SET_DATA_SOURCE_FD, data, &reply); 141 return reply.readInt32(); 142 } 143 144 status_t setDataSource(const sp<IStreamSource> &source) { 145 Parcel data, reply; 146 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 147 data.writeStrongBinder(IInterface::asBinder(source)); 148 remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply); 149 return reply.readInt32(); 150 } 151 152 status_t setDataSource(const sp<IDataSource> &source) { 153 Parcel data, reply; 154 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 155 data.writeStrongBinder(IInterface::asBinder(source)); 156 remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply); 157 return reply.readInt32(); 158 } 159 160 // pass the buffered IGraphicBufferProducer to the media player service 161 status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer) 162 { 163 Parcel data, reply; 164 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 165 sp<IBinder> b(IInterface::asBinder(bufferProducer)); 166 data.writeStrongBinder(b); 167 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply); 168 return reply.readInt32(); 169 } 170 171 status_t setBufferingSettings(const BufferingSettings& buffering) 172 { 173 Parcel data, reply; 174 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 175 buffering.writeToParcel(&data); 176 remote()->transact(SET_BUFFERING_SETTINGS, data, &reply); 177 return reply.readInt32(); 178 } 179 180 status_t getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */) 181 { 182 if (buffering == nullptr) { 183 return BAD_VALUE; 184 } 185 Parcel data, reply; 186 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 187 remote()->transact(GET_DEFAULT_BUFFERING_SETTINGS, data, &reply); 188 status_t err = reply.readInt32(); 189 if (err == OK) { 190 err = buffering->readFromParcel(&reply); 191 } 192 return err; 193 } 194 195 status_t prepareAsync() 196 { 197 Parcel data, reply; 198 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 199 remote()->transact(PREPARE_ASYNC, data, &reply); 200 return reply.readInt32(); 201 } 202 203 status_t start() 204 { 205 Parcel data, reply; 206 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 207 remote()->transact(START, data, &reply); 208 return reply.readInt32(); 209 } 210 211 status_t stop() 212 { 213 Parcel data, reply; 214 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 215 remote()->transact(STOP, data, &reply); 216 return reply.readInt32(); 217 } 218 219 status_t isPlaying(bool* state) 220 { 221 Parcel data, reply; 222 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 223 remote()->transact(IS_PLAYING, data, &reply); 224 *state = reply.readInt32(); 225 return reply.readInt32(); 226 } 227 228 status_t setPlaybackSettings(const AudioPlaybackRate& rate) 229 { 230 Parcel data, reply; 231 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 232 data.writeFloat(rate.mSpeed); 233 data.writeFloat(rate.mPitch); 234 data.writeInt32((int32_t)rate.mFallbackMode); 235 data.writeInt32((int32_t)rate.mStretchMode); 236 remote()->transact(SET_PLAYBACK_SETTINGS, data, &reply); 237 return reply.readInt32(); 238 } 239 240 status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) 241 { 242 Parcel data, reply; 243 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 244 remote()->transact(GET_PLAYBACK_SETTINGS, data, &reply); 245 status_t err = reply.readInt32(); 246 if (err == OK) { 247 *rate = AUDIO_PLAYBACK_RATE_DEFAULT; 248 rate->mSpeed = reply.readFloat(); 249 rate->mPitch = reply.readFloat(); 250 rate->mFallbackMode = (AudioTimestretchFallbackMode)reply.readInt32(); 251 rate->mStretchMode = (AudioTimestretchStretchMode)reply.readInt32(); 252 } 253 return err; 254 } 255 256 status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) 257 { 258 Parcel data, reply; 259 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 260 data.writeInt32((int32_t)sync.mSource); 261 data.writeInt32((int32_t)sync.mAudioAdjustMode); 262 data.writeFloat(sync.mTolerance); 263 data.writeFloat(videoFpsHint); 264 remote()->transact(SET_SYNC_SETTINGS, data, &reply); 265 return reply.readInt32(); 266 } 267 268 status_t getSyncSettings(AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) 269 { 270 Parcel data, reply; 271 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 272 remote()->transact(GET_SYNC_SETTINGS, data, &reply); 273 status_t err = reply.readInt32(); 274 if (err == OK) { 275 AVSyncSettings settings; 276 settings.mSource = (AVSyncSource)reply.readInt32(); 277 settings.mAudioAdjustMode = (AVSyncAudioAdjustMode)reply.readInt32(); 278 settings.mTolerance = reply.readFloat(); 279 *sync = settings; 280 *videoFps = reply.readFloat(); 281 } 282 return err; 283 } 284 285 status_t pause() 286 { 287 Parcel data, reply; 288 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 289 remote()->transact(PAUSE, data, &reply); 290 return reply.readInt32(); 291 } 292 293 status_t seekTo(int msec, MediaPlayerSeekMode mode) 294 { 295 Parcel data, reply; 296 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 297 data.writeInt32(msec); 298 data.writeInt32(mode); 299 remote()->transact(SEEK_TO, data, &reply); 300 return reply.readInt32(); 301 } 302 303 status_t getCurrentPosition(int* msec) 304 { 305 Parcel data, reply; 306 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 307 remote()->transact(GET_CURRENT_POSITION, data, &reply); 308 *msec = reply.readInt32(); 309 return reply.readInt32(); 310 } 311 312 status_t getDuration(int* msec) 313 { 314 Parcel data, reply; 315 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 316 remote()->transact(GET_DURATION, data, &reply); 317 *msec = reply.readInt32(); 318 return reply.readInt32(); 319 } 320 321 status_t reset() 322 { 323 Parcel data, reply; 324 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 325 remote()->transact(RESET, data, &reply); 326 return reply.readInt32(); 327 } 328 329 status_t setAudioStreamType(audio_stream_type_t stream) 330 { 331 Parcel data, reply; 332 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 333 data.writeInt32((int32_t) stream); 334 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply); 335 return reply.readInt32(); 336 } 337 338 status_t setLooping(int loop) 339 { 340 Parcel data, reply; 341 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 342 data.writeInt32(loop); 343 remote()->transact(SET_LOOPING, data, &reply); 344 return reply.readInt32(); 345 } 346 347 status_t setVolume(float leftVolume, float rightVolume) 348 { 349 Parcel data, reply; 350 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 351 data.writeFloat(leftVolume); 352 data.writeFloat(rightVolume); 353 remote()->transact(SET_VOLUME, data, &reply); 354 return reply.readInt32(); 355 } 356 357 status_t invoke(const Parcel& request, Parcel *reply) 358 { 359 // Avoid doing any extra copy. The interface descriptor should 360 // have been set by MediaPlayer.java. 361 return remote()->transact(INVOKE, request, reply); 362 } 363 364 status_t setMetadataFilter(const Parcel& request) 365 { 366 Parcel reply; 367 // Avoid doing any extra copy of the request. The interface 368 // descriptor should have been set by MediaPlayer.java. 369 remote()->transact(SET_METADATA_FILTER, request, &reply); 370 return reply.readInt32(); 371 } 372 373 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply) 374 { 375 Parcel request; 376 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 377 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here. 378 request.writeInt32(update_only); 379 request.writeInt32(apply_filter); 380 remote()->transact(GET_METADATA, request, reply); 381 return reply->readInt32(); 382 } 383 384 status_t setAuxEffectSendLevel(float level) 385 { 386 Parcel data, reply; 387 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 388 data.writeFloat(level); 389 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply); 390 return reply.readInt32(); 391 } 392 393 status_t attachAuxEffect(int effectId) 394 { 395 Parcel data, reply; 396 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 397 data.writeInt32(effectId); 398 remote()->transact(ATTACH_AUX_EFFECT, data, &reply); 399 return reply.readInt32(); 400 } 401 402 status_t setParameter(int key, const Parcel& request) 403 { 404 Parcel data, reply; 405 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 406 data.writeInt32(key); 407 if (request.dataSize() > 0) { 408 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize()); 409 } 410 remote()->transact(SET_PARAMETER, data, &reply); 411 return reply.readInt32(); 412 } 413 414 status_t getParameter(int key, Parcel *reply) 415 { 416 Parcel data; 417 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 418 data.writeInt32(key); 419 return remote()->transact(GET_PARAMETER, data, reply); 420 } 421 422 status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) 423 { 424 Parcel data, reply; 425 status_t err; 426 427 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 428 if (NULL != endpoint) { 429 data.writeInt32(sizeof(*endpoint)); 430 data.write(endpoint, sizeof(*endpoint)); 431 } else { 432 data.writeInt32(0); 433 } 434 435 err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply); 436 if (OK != err) { 437 return err; 438 } 439 return reply.readInt32(); 440 } 441 442 status_t setNextPlayer(const sp<IMediaPlayer>& player) { 443 Parcel data, reply; 444 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 445 sp<IBinder> b(IInterface::asBinder(player)); 446 data.writeStrongBinder(b); 447 remote()->transact(SET_NEXT_PLAYER, data, &reply); 448 return reply.readInt32(); 449 } 450 451 status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) 452 { 453 Parcel data, reply; 454 status_t err; 455 456 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 457 err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply); 458 459 if ((OK != err) || (OK != (err = reply.readInt32()))) { 460 return err; 461 } 462 463 data.read(endpoint, sizeof(*endpoint)); 464 465 return err; 466 } 467 468 virtual VolumeShaper::Status applyVolumeShaper( 469 const sp<VolumeShaper::Configuration>& configuration, 470 const sp<VolumeShaper::Operation>& operation) { 471 Parcel data, reply; 472 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 473 474 status_t tmp; 475 status_t status = configuration.get() == nullptr 476 ? data.writeInt32(0) 477 : (tmp = data.writeInt32(1)) != NO_ERROR 478 ? tmp : configuration->writeToParcel(&data); 479 if (status != NO_ERROR) { 480 return VolumeShaper::Status(status); 481 } 482 483 status = operation.get() == nullptr 484 ? status = data.writeInt32(0) 485 : (tmp = data.writeInt32(1)) != NO_ERROR 486 ? tmp : operation->writeToParcel(&data); 487 if (status != NO_ERROR) { 488 return VolumeShaper::Status(status); 489 } 490 491 int32_t remoteVolumeShaperStatus; 492 status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply); 493 if (status == NO_ERROR) { 494 status = reply.readInt32(&remoteVolumeShaperStatus); 495 } 496 if (status != NO_ERROR) { 497 return VolumeShaper::Status(status); 498 } 499 return VolumeShaper::Status(remoteVolumeShaperStatus); 500 } 501 502 virtual sp<VolumeShaper::State> getVolumeShaperState(int id) { 503 Parcel data, reply; 504 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 505 506 data.writeInt32(id); 507 status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply); 508 if (status != NO_ERROR) { 509 return nullptr; 510 } 511 sp<VolumeShaper::State> state = new VolumeShaper::State(); 512 status = state->readFromParcel(reply); 513 if (status != NO_ERROR) { 514 return nullptr; 515 } 516 return state; 517 } 518 519 // Modular DRM 520 status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) 521 { 522 Parcel data, reply; 523 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 524 525 data.write(uuid, 16); 526 writeVector(data, drmSessionId); 527 528 status_t status = remote()->transact(PREPARE_DRM, data, &reply); 529 if (status != OK) { 530 ALOGE("prepareDrm: binder call failed: %d", status); 531 return status; 532 } 533 534 return reply.readInt32(); 535 } 536 537 status_t releaseDrm() 538 { 539 Parcel data, reply; 540 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 541 542 status_t status = remote()->transact(RELEASE_DRM, data, &reply); 543 if (status != OK) { 544 ALOGE("releaseDrm: binder call failed: %d", status); 545 return status; 546 } 547 548 return reply.readInt32(); 549 } 550}; 551 552IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); 553 554// ---------------------------------------------------------------------- 555 556status_t BnMediaPlayer::onTransact( 557 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 558{ 559 switch (code) { 560 case DISCONNECT: { 561 CHECK_INTERFACE(IMediaPlayer, data, reply); 562 disconnect(); 563 return NO_ERROR; 564 } break; 565 case SET_DATA_SOURCE_URL: { 566 CHECK_INTERFACE(IMediaPlayer, data, reply); 567 568 sp<IMediaHTTPService> httpService; 569 if (data.readInt32()) { 570 httpService = 571 interface_cast<IMediaHTTPService>(data.readStrongBinder()); 572 } 573 574 const char* url = data.readCString(); 575 if (url == NULL) { 576 reply->writeInt32(BAD_VALUE); 577 return NO_ERROR; 578 } 579 KeyedVector<String8, String8> headers; 580 int32_t numHeaders = data.readInt32(); 581 for (int i = 0; i < numHeaders; ++i) { 582 String8 key = data.readString8(); 583 String8 value = data.readString8(); 584 headers.add(key, value); 585 } 586 reply->writeInt32(setDataSource( 587 httpService, url, numHeaders > 0 ? &headers : NULL)); 588 return NO_ERROR; 589 } break; 590 case SET_DATA_SOURCE_FD: { 591 CHECK_INTERFACE(IMediaPlayer, data, reply); 592 int fd = data.readFileDescriptor(); 593 int64_t offset = data.readInt64(); 594 int64_t length = data.readInt64(); 595 reply->writeInt32(setDataSource(fd, offset, length)); 596 return NO_ERROR; 597 } 598 case SET_DATA_SOURCE_STREAM: { 599 CHECK_INTERFACE(IMediaPlayer, data, reply); 600 sp<IStreamSource> source = 601 interface_cast<IStreamSource>(data.readStrongBinder()); 602 if (source == NULL) { 603 reply->writeInt32(BAD_VALUE); 604 } else { 605 reply->writeInt32(setDataSource(source)); 606 } 607 return NO_ERROR; 608 } 609 case SET_DATA_SOURCE_CALLBACK: { 610 CHECK_INTERFACE(IMediaPlayer, data, reply); 611 sp<IDataSource> source = 612 interface_cast<IDataSource>(data.readStrongBinder()); 613 if (source == NULL) { 614 reply->writeInt32(BAD_VALUE); 615 } else { 616 reply->writeInt32(setDataSource(source)); 617 } 618 return NO_ERROR; 619 } 620 case SET_VIDEO_SURFACETEXTURE: { 621 CHECK_INTERFACE(IMediaPlayer, data, reply); 622 sp<IGraphicBufferProducer> bufferProducer = 623 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 624 reply->writeInt32(setVideoSurfaceTexture(bufferProducer)); 625 return NO_ERROR; 626 } break; 627 case SET_BUFFERING_SETTINGS: { 628 CHECK_INTERFACE(IMediaPlayer, data, reply); 629 BufferingSettings buffering; 630 buffering.readFromParcel(&data); 631 reply->writeInt32(setBufferingSettings(buffering)); 632 return NO_ERROR; 633 } break; 634 case GET_DEFAULT_BUFFERING_SETTINGS: { 635 CHECK_INTERFACE(IMediaPlayer, data, reply); 636 BufferingSettings buffering; 637 status_t err = getDefaultBufferingSettings(&buffering); 638 reply->writeInt32(err); 639 if (err == OK) { 640 buffering.writeToParcel(reply); 641 } 642 return NO_ERROR; 643 } break; 644 case PREPARE_ASYNC: { 645 CHECK_INTERFACE(IMediaPlayer, data, reply); 646 reply->writeInt32(prepareAsync()); 647 return NO_ERROR; 648 } break; 649 case START: { 650 CHECK_INTERFACE(IMediaPlayer, data, reply); 651 reply->writeInt32(start()); 652 return NO_ERROR; 653 } break; 654 case STOP: { 655 CHECK_INTERFACE(IMediaPlayer, data, reply); 656 reply->writeInt32(stop()); 657 return NO_ERROR; 658 } break; 659 case IS_PLAYING: { 660 CHECK_INTERFACE(IMediaPlayer, data, reply); 661 bool state; 662 status_t ret = isPlaying(&state); 663 reply->writeInt32(state); 664 reply->writeInt32(ret); 665 return NO_ERROR; 666 } break; 667 case SET_PLAYBACK_SETTINGS: { 668 CHECK_INTERFACE(IMediaPlayer, data, reply); 669 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; 670 rate.mSpeed = data.readFloat(); 671 rate.mPitch = data.readFloat(); 672 rate.mFallbackMode = (AudioTimestretchFallbackMode)data.readInt32(); 673 rate.mStretchMode = (AudioTimestretchStretchMode)data.readInt32(); 674 reply->writeInt32(setPlaybackSettings(rate)); 675 return NO_ERROR; 676 } break; 677 case GET_PLAYBACK_SETTINGS: { 678 CHECK_INTERFACE(IMediaPlayer, data, reply); 679 AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT; 680 status_t err = getPlaybackSettings(&rate); 681 reply->writeInt32(err); 682 if (err == OK) { 683 reply->writeFloat(rate.mSpeed); 684 reply->writeFloat(rate.mPitch); 685 reply->writeInt32((int32_t)rate.mFallbackMode); 686 reply->writeInt32((int32_t)rate.mStretchMode); 687 } 688 return NO_ERROR; 689 } break; 690 case SET_SYNC_SETTINGS: { 691 CHECK_INTERFACE(IMediaPlayer, data, reply); 692 AVSyncSettings sync; 693 sync.mSource = (AVSyncSource)data.readInt32(); 694 sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)data.readInt32(); 695 sync.mTolerance = data.readFloat(); 696 float videoFpsHint = data.readFloat(); 697 reply->writeInt32(setSyncSettings(sync, videoFpsHint)); 698 return NO_ERROR; 699 } break; 700 case GET_SYNC_SETTINGS: { 701 CHECK_INTERFACE(IMediaPlayer, data, reply); 702 AVSyncSettings sync; 703 float videoFps; 704 status_t err = getSyncSettings(&sync, &videoFps); 705 reply->writeInt32(err); 706 if (err == OK) { 707 reply->writeInt32((int32_t)sync.mSource); 708 reply->writeInt32((int32_t)sync.mAudioAdjustMode); 709 reply->writeFloat(sync.mTolerance); 710 reply->writeFloat(videoFps); 711 } 712 return NO_ERROR; 713 } break; 714 case PAUSE: { 715 CHECK_INTERFACE(IMediaPlayer, data, reply); 716 reply->writeInt32(pause()); 717 return NO_ERROR; 718 } break; 719 case SEEK_TO: { 720 CHECK_INTERFACE(IMediaPlayer, data, reply); 721 int msec = data.readInt32(); 722 MediaPlayerSeekMode mode = (MediaPlayerSeekMode)data.readInt32(); 723 reply->writeInt32(seekTo(msec, mode)); 724 return NO_ERROR; 725 } break; 726 case GET_CURRENT_POSITION: { 727 CHECK_INTERFACE(IMediaPlayer, data, reply); 728 int msec = 0; 729 status_t ret = getCurrentPosition(&msec); 730 reply->writeInt32(msec); 731 reply->writeInt32(ret); 732 return NO_ERROR; 733 } break; 734 case GET_DURATION: { 735 CHECK_INTERFACE(IMediaPlayer, data, reply); 736 int msec = 0; 737 status_t ret = getDuration(&msec); 738 reply->writeInt32(msec); 739 reply->writeInt32(ret); 740 return NO_ERROR; 741 } break; 742 case RESET: { 743 CHECK_INTERFACE(IMediaPlayer, data, reply); 744 reply->writeInt32(reset()); 745 return NO_ERROR; 746 } break; 747 case SET_AUDIO_STREAM_TYPE: { 748 CHECK_INTERFACE(IMediaPlayer, data, reply); 749 reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32())); 750 return NO_ERROR; 751 } break; 752 case SET_LOOPING: { 753 CHECK_INTERFACE(IMediaPlayer, data, reply); 754 reply->writeInt32(setLooping(data.readInt32())); 755 return NO_ERROR; 756 } break; 757 case SET_VOLUME: { 758 CHECK_INTERFACE(IMediaPlayer, data, reply); 759 float leftVolume = data.readFloat(); 760 float rightVolume = data.readFloat(); 761 reply->writeInt32(setVolume(leftVolume, rightVolume)); 762 return NO_ERROR; 763 } break; 764 case INVOKE: { 765 CHECK_INTERFACE(IMediaPlayer, data, reply); 766 status_t result = invoke(data, reply); 767 return result; 768 } break; 769 case SET_METADATA_FILTER: { 770 CHECK_INTERFACE(IMediaPlayer, data, reply); 771 reply->writeInt32(setMetadataFilter(data)); 772 return NO_ERROR; 773 } break; 774 case GET_METADATA: { 775 CHECK_INTERFACE(IMediaPlayer, data, reply); 776 bool update_only = static_cast<bool>(data.readInt32()); 777 bool apply_filter = static_cast<bool>(data.readInt32()); 778 const status_t retcode = getMetadata(update_only, apply_filter, reply); 779 reply->setDataPosition(0); 780 reply->writeInt32(retcode); 781 reply->setDataPosition(0); 782 return NO_ERROR; 783 } break; 784 case SET_AUX_EFFECT_SEND_LEVEL: { 785 CHECK_INTERFACE(IMediaPlayer, data, reply); 786 reply->writeInt32(setAuxEffectSendLevel(data.readFloat())); 787 return NO_ERROR; 788 } break; 789 case ATTACH_AUX_EFFECT: { 790 CHECK_INTERFACE(IMediaPlayer, data, reply); 791 reply->writeInt32(attachAuxEffect(data.readInt32())); 792 return NO_ERROR; 793 } break; 794 case SET_PARAMETER: { 795 CHECK_INTERFACE(IMediaPlayer, data, reply); 796 int key = data.readInt32(); 797 798 Parcel request; 799 if (data.dataAvail() > 0) { 800 request.appendFrom( 801 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); 802 } 803 request.setDataPosition(0); 804 reply->writeInt32(setParameter(key, request)); 805 return NO_ERROR; 806 } break; 807 case GET_PARAMETER: { 808 CHECK_INTERFACE(IMediaPlayer, data, reply); 809 return getParameter(data.readInt32(), reply); 810 } break; 811 case SET_RETRANSMIT_ENDPOINT: { 812 CHECK_INTERFACE(IMediaPlayer, data, reply); 813 814 struct sockaddr_in endpoint; 815 memset(&endpoint, 0, sizeof(endpoint)); 816 int amt = data.readInt32(); 817 if (amt == sizeof(endpoint)) { 818 data.read(&endpoint, sizeof(struct sockaddr_in)); 819 reply->writeInt32(setRetransmitEndpoint(&endpoint)); 820 } else { 821 reply->writeInt32(setRetransmitEndpoint(NULL)); 822 } 823 824 return NO_ERROR; 825 } break; 826 case GET_RETRANSMIT_ENDPOINT: { 827 CHECK_INTERFACE(IMediaPlayer, data, reply); 828 829 struct sockaddr_in endpoint; 830 memset(&endpoint, 0, sizeof(endpoint)); 831 status_t res = getRetransmitEndpoint(&endpoint); 832 833 reply->writeInt32(res); 834 reply->write(&endpoint, sizeof(endpoint)); 835 836 return NO_ERROR; 837 } break; 838 case SET_NEXT_PLAYER: { 839 CHECK_INTERFACE(IMediaPlayer, data, reply); 840 reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder()))); 841 842 return NO_ERROR; 843 } break; 844 845 case APPLY_VOLUME_SHAPER: { 846 CHECK_INTERFACE(IMediaPlayer, data, reply); 847 sp<VolumeShaper::Configuration> configuration; 848 sp<VolumeShaper::Operation> operation; 849 850 int32_t present; 851 status_t status = data.readInt32(&present); 852 if (status == NO_ERROR && present != 0) { 853 configuration = new VolumeShaper::Configuration(); 854 status = configuration->readFromParcel(data); 855 } 856 if (status == NO_ERROR) { 857 status = data.readInt32(&present); 858 } 859 if (status == NO_ERROR && present != 0) { 860 operation = new VolumeShaper::Operation(); 861 status = operation->readFromParcel(data); 862 } 863 if (status == NO_ERROR) { 864 status = (status_t)applyVolumeShaper(configuration, operation); 865 } 866 reply->writeInt32(status); 867 return NO_ERROR; 868 } break; 869 case GET_VOLUME_SHAPER_STATE: { 870 CHECK_INTERFACE(IMediaPlayer, data, reply); 871 int id; 872 status_t status = data.readInt32(&id); 873 if (status == NO_ERROR) { 874 sp<VolumeShaper::State> state = getVolumeShaperState(id); 875 if (state.get() != nullptr) { 876 status = state->writeToParcel(reply); 877 } 878 } 879 return NO_ERROR; 880 } break; 881 882 // Modular DRM 883 case PREPARE_DRM: { 884 CHECK_INTERFACE(IMediaPlayer, data, reply); 885 886 uint8_t uuid[16]; 887 data.read(uuid, sizeof(uuid)); 888 Vector<uint8_t> drmSessionId; 889 readVector(data, drmSessionId); 890 891 uint32_t result = prepareDrm(uuid, drmSessionId); 892 reply->writeInt32(result); 893 return OK; 894 } 895 case RELEASE_DRM: { 896 CHECK_INTERFACE(IMediaPlayer, data, reply); 897 898 uint32_t result = releaseDrm(); 899 reply->writeInt32(result); 900 return OK; 901 } 902 default: 903 return BBinder::onTransact(code, data, reply, flags); 904 } 905} 906 907// ---------------------------------------------------------------------------- 908 909} // namespace android 910