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