IMediaPlayer.cpp revision 6b74d671a1321a6ecc4a40b6c87beedfecc1ec44
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Copyright 2008, The Android Open Source Project
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** you may not use this file except in compliance with the License.
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** You may obtain a copy of the License at
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** See the License for the specific language governing permissions and
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** limitations under the License.
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project*/
17d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
18d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian#include <arpa/inet.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <binder/Parcel.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <media/IMediaPlayer.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <media/IStreamSource.h>
26076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <gui/ISurfaceTexture.h>
288630320433bd15aca239522e54e711ef6372ab07Mathias Agopian#include <utils/String8.h>
294f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian
308630320433bd15aca239522e54e711ef6372ab07Mathias Agopiannamespace android {
318630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
32f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopianenum {
33f435863467ab407f2a482604beed5fa6f0144c62Mathias Agopian    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
341b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    SET_DATA_SOURCE_URL,
351f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    SET_DATA_SOURCE_FD,
36d8552d796cbcb9a89711fc8f97b34838da5cbdb7Mathias Agopian    SET_DATA_SOURCE_STREAM,
37d8552d796cbcb9a89711fc8f97b34838da5cbdb7Mathias Agopian    PREPARE_ASYNC,
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    START,
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    STOP,
40c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    IS_PLAYING,
4199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    PAUSE,
429e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    SEEK_TO,
4313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    GET_CURRENT_POSITION,
448630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    GET_DURATION,
45da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    RESET,
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SET_AUDIO_STREAM_TYPE,
47028a7572c81f91e4039b694cde1f55fdb3e483c7Mathias Agopian    SET_LOOPING,
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SET_VOLUME,
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    INVOKE,
5087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    SET_METADATA_FILTER,
5187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    GET_METADATA,
5287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    SET_AUX_EFFECT_SEND_LEVEL,
5387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    ATTACH_AUX_EFFECT,
5487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    SET_VIDEO_SURFACETEXTURE,
5587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    SET_PARAMETER,
563eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian    GET_PARAMETER,
573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    SET_RETRANSMIT_ENDPOINT,
583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    SET_NEXT_PLAYER,
593ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian};
603ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
619e663de4fe1dcc872373ee530c60a375624671c3Jesse Hallclass BpMediaPlayer: public BpInterface<IMediaPlayer>
629e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall{
6392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopianpublic:
6492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    BpMediaPlayer(const sp<IBinder>& impl)
6592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        : BpInterface<IMediaPlayer>(impl)
6687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    {
6787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    }
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // disconnect from media player service
7001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    void disconnect()
7101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    {
7201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        Parcel data, reply;
7301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
740f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        remote()->transact(DISCONNECT, data, &reply);
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
76dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
77ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    status_t setDataSource(const char* url,
78dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            const KeyedVector<String8, String8>* headers)
79dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    {
8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        Parcel data, reply;
81db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
82a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        data.writeCString(url);
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (headers == NULL) {
84028a7572c81f91e4039b694cde1f55fdb3e483c7Mathias Agopian            data.writeInt32(0);
8592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        } else {
8692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // serialize the headers
8792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            data.writeInt32(headers->size());
8892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i = 0; i < headers->size(); ++i) {
8992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                data.writeString8(headers->keyAt(i));
90dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis                data.writeString8(headers->valueAt(i));
91dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            }
92dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        }
93dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return reply.readInt32();
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t setDataSource(int fd, int64_t offset, int64_t length) {
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Parcel data, reply;
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        data.writeFileDescriptor(fd);
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        data.writeInt64(offset);
1023eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian        data.writeInt64(length);
103a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
1043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return reply.readInt32();
10513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
10613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian
1073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    status_t setDataSource(const sp<IStreamSource> &source) {
108cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        Parcel data, reply;
1093b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
11028947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian        data.writeStrongBinder(source->asBinder());
11100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
11228947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian        return reply.readInt32();
1131b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    }
114c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
1151b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    // pass the buffered ISurfaceTexture to the media player service
116f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
117f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    {
118766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        Parcel data, reply;
119eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
120da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        sp<IBinder> b(surfaceTexture->asBinder());
12187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        data.writeStrongBinder(b);
1223ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
123e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        return reply.readInt32();
1243ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
12587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
126028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    status_t prepareAsync()
12738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    {
12838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        Parcel data, reply;
129da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
13074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian        remote()->transact(PREPARE_ASYNC, data, &reply);
13101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        return reply.readInt32();
132da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
133da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
134da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    status_t start()
1359c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    {
1361b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        Parcel data, reply;
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
1389c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        remote()->transact(START, data, &reply);
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return reply.readInt32();
1409e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian    }
1418dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden
1428dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    status_t stop()
143875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    {
144875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        Parcel data, reply;
145bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
146d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        remote()->transact(STOP, data, &reply);
1478dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden        return reply.readInt32();
148d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
149d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
150d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    status_t isPlaying(bool* state)
151d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    {
152d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        Parcel data, reply;
153d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
15402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        remote()->transact(IS_PLAYING, data, &reply);
15502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        *state = reply.readInt32();
15602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        return reply.readInt32();
157d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
158d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
159d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    status_t pause()
160d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    {
16174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        Parcel data, reply;
162d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        remote()->transact(PAUSE, data, &reply);
164a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        return reply.readInt32();
165a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
166a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
167c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian    status_t seekTo(int msec)
1683ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    {
169e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        Parcel data, reply;
1703ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
171d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        data.writeInt32(msec);
172a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        remote()->transact(SEEK_TO, data, &reply);
173d8552d796cbcb9a89711fc8f97b34838da5cbdb7Mathias Agopian        return reply.readInt32();
17499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    }
175a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t getCurrentPosition(int* msec)
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
1781b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        Parcel data, reply;
1791b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        remote()->transact(GET_CURRENT_POSITION, data, &reply);
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *msec = reply.readInt32();
182076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return reply.readInt32();
1838dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    }
184dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
18503e407270c7ad76632f982c886d0776bed9e9b4cMathias Agopian    status_t getDuration(int* msec)
186a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    {
187a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        Parcel data, reply;
188a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
189a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        remote()->transact(GET_DURATION, data, &reply);
190d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        *msec = reply.readInt32();
1913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return reply.readInt32();
19213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    }
193d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
1943b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    status_t reset()
1953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    {
1963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Parcel data, reply;
197d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
198d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        remote()->transact(RESET, data, &reply);
199d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        return reply.readInt32();
200a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
201d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
202d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    status_t setAudioStreamType(audio_stream_type_t stream)
203d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    {
204da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        Parcel data, reply;
205da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
206da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        data.writeInt32((int32_t) stream);
20787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
208da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        return reply.readInt32();
209766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian    }
210da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
211766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian    status_t setLooping(int loop)
212da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    {
213766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        Parcel data, reply;
214766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
215da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        data.writeInt32(loop);
216eba8c688f633f3f3f1b75c2bc64faf799dd2b5f2Mathias Agopian        remote()->transact(SET_LOOPING, data, &reply);
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return reply.readInt32();
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t setVolume(float leftVolume, float rightVolume)
221d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    {
222        Parcel data, reply;
223        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
224        data.writeFloat(leftVolume);
225        data.writeFloat(rightVolume);
226        remote()->transact(SET_VOLUME, data, &reply);
227        return reply.readInt32();
228    }
229
230    status_t invoke(const Parcel& request, Parcel *reply)
231    {
232        // Avoid doing any extra copy. The interface descriptor should
233        // have been set by MediaPlayer.java.
234        return remote()->transact(INVOKE, request, reply);
235    }
236
237    status_t setMetadataFilter(const Parcel& request)
238    {
239        Parcel reply;
240        // Avoid doing any extra copy of the request. The interface
241        // descriptor should have been set by MediaPlayer.java.
242        remote()->transact(SET_METADATA_FILTER, request, &reply);
243        return reply.readInt32();
244    }
245
246    status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
247    {
248        Parcel request;
249        request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
250        // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
251        request.writeInt32(update_only);
252        request.writeInt32(apply_filter);
253        remote()->transact(GET_METADATA, request, reply);
254        return reply->readInt32();
255    }
256
257    status_t setAuxEffectSendLevel(float level)
258    {
259        Parcel data, reply;
260        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
261        data.writeFloat(level);
262        remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
263        return reply.readInt32();
264    }
265
266    status_t attachAuxEffect(int effectId)
267    {
268        Parcel data, reply;
269        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
270        data.writeInt32(effectId);
271        remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
272        return reply.readInt32();
273    }
274
275    status_t setParameter(int key, const Parcel& request)
276    {
277        Parcel data, reply;
278        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
279        data.writeInt32(key);
280        if (request.dataSize() > 0) {
281            data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
282        }
283        remote()->transact(SET_PARAMETER, data, &reply);
284        return reply.readInt32();
285    }
286
287    status_t getParameter(int key, Parcel *reply)
288    {
289        Parcel data;
290        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
291        data.writeInt32(key);
292        return remote()->transact(GET_PARAMETER, data, reply);
293    }
294
295    status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) {
296        Parcel data, reply;
297        status_t err;
298
299        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
300        if (NULL != endpoint) {
301            data.writeInt32(sizeof(*endpoint));
302            data.write(endpoint, sizeof(*endpoint));
303        } else {
304            data.writeInt32(0);
305        }
306
307        err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply);
308        if (OK != err) {
309            return err;
310        }
311        return reply.readInt32();
312    }
313
314    status_t setNextPlayer(const sp<IMediaPlayer>& player) {
315        Parcel data, reply;
316        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
317        sp<IBinder> b(player->asBinder());
318        data.writeStrongBinder(b);
319        remote()->transact(SET_NEXT_PLAYER, data, &reply);
320        return reply.readInt32();
321    }
322};
323
324IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
325
326// ----------------------------------------------------------------------
327
328status_t BnMediaPlayer::onTransact(
329    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
330{
331    switch(code) {
332        case DISCONNECT: {
333            CHECK_INTERFACE(IMediaPlayer, data, reply);
334            disconnect();
335            return NO_ERROR;
336        } break;
337        case SET_DATA_SOURCE_URL: {
338            CHECK_INTERFACE(IMediaPlayer, data, reply);
339            const char* url = data.readCString();
340            KeyedVector<String8, String8> headers;
341            int32_t numHeaders = data.readInt32();
342            for (int i = 0; i < numHeaders; ++i) {
343                String8 key = data.readString8();
344                String8 value = data.readString8();
345                headers.add(key, value);
346            }
347            reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers : NULL));
348            return NO_ERROR;
349        } break;
350        case SET_DATA_SOURCE_FD: {
351            CHECK_INTERFACE(IMediaPlayer, data, reply);
352            int fd = data.readFileDescriptor();
353            int64_t offset = data.readInt64();
354            int64_t length = data.readInt64();
355            reply->writeInt32(setDataSource(fd, offset, length));
356            return NO_ERROR;
357        }
358        case SET_DATA_SOURCE_STREAM: {
359            CHECK_INTERFACE(IMediaPlayer, data, reply);
360            sp<IStreamSource> source =
361                interface_cast<IStreamSource>(data.readStrongBinder());
362            reply->writeInt32(setDataSource(source));
363            return NO_ERROR;
364        }
365        case SET_VIDEO_SURFACETEXTURE: {
366            CHECK_INTERFACE(IMediaPlayer, data, reply);
367            sp<ISurfaceTexture> surfaceTexture =
368                    interface_cast<ISurfaceTexture>(data.readStrongBinder());
369            reply->writeInt32(setVideoSurfaceTexture(surfaceTexture));
370            return NO_ERROR;
371        } break;
372        case PREPARE_ASYNC: {
373            CHECK_INTERFACE(IMediaPlayer, data, reply);
374            reply->writeInt32(prepareAsync());
375            return NO_ERROR;
376        } break;
377        case START: {
378            CHECK_INTERFACE(IMediaPlayer, data, reply);
379            reply->writeInt32(start());
380            return NO_ERROR;
381        } break;
382        case STOP: {
383            CHECK_INTERFACE(IMediaPlayer, data, reply);
384            reply->writeInt32(stop());
385            return NO_ERROR;
386        } break;
387        case IS_PLAYING: {
388            CHECK_INTERFACE(IMediaPlayer, data, reply);
389            bool state;
390            status_t ret = isPlaying(&state);
391            reply->writeInt32(state);
392            reply->writeInt32(ret);
393            return NO_ERROR;
394        } break;
395        case PAUSE: {
396            CHECK_INTERFACE(IMediaPlayer, data, reply);
397            reply->writeInt32(pause());
398            return NO_ERROR;
399        } break;
400        case SEEK_TO: {
401            CHECK_INTERFACE(IMediaPlayer, data, reply);
402            reply->writeInt32(seekTo(data.readInt32()));
403            return NO_ERROR;
404        } break;
405        case GET_CURRENT_POSITION: {
406            CHECK_INTERFACE(IMediaPlayer, data, reply);
407            int msec;
408            status_t ret = getCurrentPosition(&msec);
409            reply->writeInt32(msec);
410            reply->writeInt32(ret);
411            return NO_ERROR;
412        } break;
413        case GET_DURATION: {
414            CHECK_INTERFACE(IMediaPlayer, data, reply);
415            int msec;
416            status_t ret = getDuration(&msec);
417            reply->writeInt32(msec);
418            reply->writeInt32(ret);
419            return NO_ERROR;
420        } break;
421        case RESET: {
422            CHECK_INTERFACE(IMediaPlayer, data, reply);
423            reply->writeInt32(reset());
424            return NO_ERROR;
425        } break;
426        case SET_AUDIO_STREAM_TYPE: {
427            CHECK_INTERFACE(IMediaPlayer, data, reply);
428            reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
429            return NO_ERROR;
430        } break;
431        case SET_LOOPING: {
432            CHECK_INTERFACE(IMediaPlayer, data, reply);
433            reply->writeInt32(setLooping(data.readInt32()));
434            return NO_ERROR;
435        } break;
436        case SET_VOLUME: {
437            CHECK_INTERFACE(IMediaPlayer, data, reply);
438            float leftVolume = data.readFloat();
439            float rightVolume = data.readFloat();
440            reply->writeInt32(setVolume(leftVolume, rightVolume));
441            return NO_ERROR;
442        } break;
443        case INVOKE: {
444            CHECK_INTERFACE(IMediaPlayer, data, reply);
445            status_t result = invoke(data, reply);
446            return result;
447        } break;
448        case SET_METADATA_FILTER: {
449            CHECK_INTERFACE(IMediaPlayer, data, reply);
450            reply->writeInt32(setMetadataFilter(data));
451            return NO_ERROR;
452        } break;
453        case GET_METADATA: {
454            CHECK_INTERFACE(IMediaPlayer, data, reply);
455            bool update_only = static_cast<bool>(data.readInt32());
456            bool apply_filter = static_cast<bool>(data.readInt32());
457            const status_t retcode = getMetadata(update_only, apply_filter, reply);
458            reply->setDataPosition(0);
459            reply->writeInt32(retcode);
460            reply->setDataPosition(0);
461            return NO_ERROR;
462        } break;
463        case SET_AUX_EFFECT_SEND_LEVEL: {
464            CHECK_INTERFACE(IMediaPlayer, data, reply);
465            reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
466            return NO_ERROR;
467        } break;
468        case ATTACH_AUX_EFFECT: {
469            CHECK_INTERFACE(IMediaPlayer, data, reply);
470            reply->writeInt32(attachAuxEffect(data.readInt32()));
471            return NO_ERROR;
472        } break;
473        case SET_PARAMETER: {
474            CHECK_INTERFACE(IMediaPlayer, data, reply);
475            int key = data.readInt32();
476
477            Parcel request;
478            if (data.dataAvail() > 0) {
479                request.appendFrom(
480                        const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
481            }
482            request.setDataPosition(0);
483            reply->writeInt32(setParameter(key, request));
484            return NO_ERROR;
485        } break;
486        case GET_PARAMETER: {
487            CHECK_INTERFACE(IMediaPlayer, data, reply);
488            return getParameter(data.readInt32(), reply);
489        } break;
490        case SET_RETRANSMIT_ENDPOINT: {
491            CHECK_INTERFACE(IMediaPlayer, data, reply);
492
493            struct sockaddr_in endpoint;
494            int amt = data.readInt32();
495            if (amt == sizeof(endpoint)) {
496                data.read(&endpoint, sizeof(struct sockaddr_in));
497                reply->writeInt32(setRetransmitEndpoint(&endpoint));
498            } else {
499                reply->writeInt32(setRetransmitEndpoint(NULL));
500            }
501            return NO_ERROR;
502        } break;
503        case SET_NEXT_PLAYER: {
504            CHECK_INTERFACE(IMediaPlayer, data, reply);
505            reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder())));
506            return NO_ERROR;
507        } break;
508        default:
509            return BBinder::onTransact(code, data, reply, flags);
510    }
511}
512
513// ----------------------------------------------------------------------------
514
515}; // namespace android
516