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