IMediaPlayer.cpp revision 89fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams**
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** Copyright 2008, The Android Open Source Project
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams**
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** Licensed under the Apache License, Version 2.0 (the "License");
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** you may not use this file except in compliance with the License.
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** You may obtain a copy of the License at
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams**
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams**     http://www.apache.org/licenses/LICENSE-2.0
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams**
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** Unless required by applicable law or agreed to in writing, software
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** distributed under the License is distributed on an "AS IS" BASIS,
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** See the License for the specific language governing permissions and
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** limitations under the License.
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams*/
17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <stdint.h>
19326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <sys/types.h>
20326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
21326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <utils/Parcel.h>
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
23326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <media/IMediaPlayer.h>
24326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <ui/ISurface.h>
25326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
265c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Samsnamespace android {
27326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
28326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsenum {
29326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
30326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    SET_VIDEO_SURFACE,
31326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    PREPARE_ASYNC,
32326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    START,
33326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    STOP,
34326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    IS_PLAYING,
35e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    PAUSE,
36fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    SEEK_TO,
37fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    GET_CURRENT_POSITION,
38326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    GET_DURATION,
39326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    RESET,
40326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    SET_AUDIO_STREAM_TYPE,
41326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    SET_LOOPING,
42326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    SET_VOLUME
43326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams};
44326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
45326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsclass BpMediaPlayer: public BpInterface<IMediaPlayer>
46326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
47326e0ddf89e8df2837752fbfd7a014814b32082cJason Samspublic:
48326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    BpMediaPlayer(const sp<IBinder>& impl)
49326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        : BpInterface<IMediaPlayer>(impl)
507fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    {
51cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
52326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
53326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    // disconnect from media player service
54cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    void disconnect()
55cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    {
56326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        Parcel data, reply;
57326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        remote()->transact(DISCONNECT, data, &reply);
599397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
609397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
61e5ffb879ae535a899a486285a23bea05e912480fJason Sams    status_t setVideoSurface(const sp<ISurface>& surface)
629397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    {
63326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        Parcel data, reply;
649397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
65326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeStrongBinder(surface->asBinder());
66e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams        remote()->transact(SET_VIDEO_SURFACE, data, &reply);
67e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams        return reply.readInt32();
68e5ffb879ae535a899a486285a23bea05e912480fJason Sams    }
69e5ffb879ae535a899a486285a23bea05e912480fJason Sams
70e5ffb879ae535a899a486285a23bea05e912480fJason Sams    status_t prepareAsync()
715c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    {
725c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        Parcel data, reply;
73e5ffb879ae535a899a486285a23bea05e912480fJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
743dd429cc32388ca0c3d7a9368ed2e348b8fdaab1Jason Sams        remote()->transact(PREPARE_ASYNC, data, &reply);
75fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return reply.readInt32();
76fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
77fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
78e5ffb879ae535a899a486285a23bea05e912480fJason Sams    status_t start()
79cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    {
80cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        Parcel data, reply;
81326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
825c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        remote()->transact(START, data, &reply);
835c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        return reply.readInt32();
84326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
85326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
86326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    status_t stop()
875c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    {
885c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        Parcel data, reply;
89fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
90fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        remote()->transact(STOP, data, &reply);
91fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        return reply.readInt32();
92fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
93fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
94326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    status_t isPlaying(bool* state)
95326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    {
96326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        Parcel data, reply;
97326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
98326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        remote()->transact(IS_PLAYING, data, &reply);
99326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        *state = reply.readInt32();
100326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        return reply.readInt32();
101326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
102326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
103326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    status_t pause()
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    {
105326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        Parcel data, reply;
106326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
107326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        remote()->transact(PAUSE, data, &reply);
108326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        return reply.readInt32();
109326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
1107fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams
111cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    status_t seekTo(int msec)
112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    {
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        Parcel data, reply;
114326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
115326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        data.writeInt32(msec);
116326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        remote()->transact(SEEK_TO, data, &reply);
117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        return reply.readInt32();
118326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
119cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
120cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    status_t getCurrentPosition(int* msec)
121fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    {
122fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        Parcel data, reply;
123fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
124fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        remote()->transact(GET_CURRENT_POSITION, data, &reply);
125326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        *msec = reply.readInt32();
126326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        return reply.readInt32();
127326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
128326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
129326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    status_t getDuration(int* msec)
130326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    {
131        Parcel data, reply;
132        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
133        remote()->transact(GET_DURATION, data, &reply);
134        *msec = reply.readInt32();
135        return reply.readInt32();
136    }
137
138    status_t reset()
139    {
140        Parcel data, reply;
141        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
142        remote()->transact(RESET, data, &reply);
143        return reply.readInt32();
144    }
145
146    status_t setAudioStreamType(int type)
147    {
148        Parcel data, reply;
149        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
150        data.writeInt32(type);
151        remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
152        return reply.readInt32();
153    }
154
155    status_t setLooping(int loop)
156    {
157        Parcel data, reply;
158        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
159        data.writeInt32(loop);
160        remote()->transact(SET_LOOPING, data, &reply);
161        return reply.readInt32();
162    }
163
164    status_t setVolume(float leftVolume, float rightVolume)
165    {
166        Parcel data, reply;
167        data.writeFloat(leftVolume);
168        data.writeFloat(rightVolume);
169        remote()->transact(SET_VOLUME, data, &reply);
170        return reply.readInt32();
171    }
172};
173
174IMPLEMENT_META_INTERFACE(MediaPlayer, "android.hardware.IMediaPlayer");
175
176// ----------------------------------------------------------------------
177
178#define CHECK_INTERFACE(interface, data, reply) \
179        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
180            LOGW("Call incorrectly routed to " #interface); \
181            return PERMISSION_DENIED; \
182        } } while (0)
183
184status_t BnMediaPlayer::onTransact(
185    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
186{
187    switch(code) {
188        case DISCONNECT: {
189            CHECK_INTERFACE(IMediaPlayer, data, reply);
190            disconnect();
191            return NO_ERROR;
192        } break;
193        case SET_VIDEO_SURFACE: {
194            CHECK_INTERFACE(IMediaPlayer, data, reply);
195            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
196            reply->writeInt32(setVideoSurface(surface));
197            return NO_ERROR;
198        } break;
199        case PREPARE_ASYNC: {
200            CHECK_INTERFACE(IMediaPlayer, data, reply);
201            reply->writeInt32(prepareAsync());
202            return NO_ERROR;
203        } break;
204        case START: {
205            CHECK_INTERFACE(IMediaPlayer, data, reply);
206            reply->writeInt32(start());
207            return NO_ERROR;
208        } break;
209        case STOP: {
210            CHECK_INTERFACE(IMediaPlayer, data, reply);
211            reply->writeInt32(stop());
212            return NO_ERROR;
213        } break;
214        case IS_PLAYING: {
215            CHECK_INTERFACE(IMediaPlayer, data, reply);
216            bool state;
217            status_t ret = isPlaying(&state);
218            reply->writeInt32(state);
219            reply->writeInt32(ret);
220            return NO_ERROR;
221        } break;
222        case PAUSE: {
223            CHECK_INTERFACE(IMediaPlayer, data, reply);
224            reply->writeInt32(pause());
225            return NO_ERROR;
226        } break;
227        case SEEK_TO: {
228            CHECK_INTERFACE(IMediaPlayer, data, reply);
229            reply->writeInt32(seekTo(data.readInt32()));
230            return NO_ERROR;
231        } break;
232        case GET_CURRENT_POSITION: {
233            CHECK_INTERFACE(IMediaPlayer, data, reply);
234            int msec;
235            status_t ret = getCurrentPosition(&msec);
236            reply->writeInt32(msec);
237            reply->writeInt32(ret);
238            return NO_ERROR;
239        } break;
240        case GET_DURATION: {
241            CHECK_INTERFACE(IMediaPlayer, data, reply);
242            int msec;
243            status_t ret = getDuration(&msec);
244            reply->writeInt32(msec);
245            reply->writeInt32(ret);
246            return NO_ERROR;
247        } break;
248        case RESET: {
249            CHECK_INTERFACE(IMediaPlayer, data, reply);
250            reply->writeInt32(reset());
251            return NO_ERROR;
252        } break;
253        case SET_AUDIO_STREAM_TYPE: {
254            CHECK_INTERFACE(IMediaPlayer, data, reply);
255            reply->writeInt32(setAudioStreamType(data.readInt32()));
256            return NO_ERROR;
257        } break;
258        case SET_LOOPING: {
259            CHECK_INTERFACE(IMediaPlayer, data, reply);
260            reply->writeInt32(setLooping(data.readInt32()));
261            return NO_ERROR;
262        } break;
263        case SET_VOLUME: {
264            reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
265            return NO_ERROR;
266        } break;
267        default:
268            return BBinder::onTransact(code, data, reply, flags);
269    }
270}
271
272// ----------------------------------------------------------------------------
273
274}; // namespace android
275
276