IMediaPlayer.cpp revision a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9
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 <stdint.h>
19#include <sys/types.h>
20
21#include <binder/Parcel.h>
22
23#include <media/IMediaPlayer.h>
24#include <ui/ISurface.h>
25
26namespace android {
27
28enum {
29    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
30    SET_VIDEO_SURFACE,
31    PREPARE_ASYNC,
32    START,
33    STOP,
34    IS_PLAYING,
35    PAUSE,
36    SEEK_TO,
37    GET_CURRENT_POSITION,
38    GET_DURATION,
39    RESET,
40    SET_AUDIO_STREAM_TYPE,
41    SET_LOOPING,
42    SET_VOLUME,
43    INVOKE,
44    SET_METADATA_FILTER,
45};
46
47class BpMediaPlayer: public BpInterface<IMediaPlayer>
48{
49public:
50    BpMediaPlayer(const sp<IBinder>& impl)
51        : BpInterface<IMediaPlayer>(impl)
52    {
53    }
54
55    // disconnect from media player service
56    void disconnect()
57    {
58        Parcel data, reply;
59        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
60        remote()->transact(DISCONNECT, data, &reply);
61    }
62
63    status_t setVideoSurface(const sp<ISurface>& surface)
64    {
65        Parcel data, reply;
66        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
67        data.writeStrongBinder(surface->asBinder());
68        remote()->transact(SET_VIDEO_SURFACE, data, &reply);
69        return reply.readInt32();
70    }
71
72    status_t prepareAsync()
73    {
74        Parcel data, reply;
75        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
76        remote()->transact(PREPARE_ASYNC, data, &reply);
77        return reply.readInt32();
78    }
79
80    status_t start()
81    {
82        Parcel data, reply;
83        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
84        remote()->transact(START, data, &reply);
85        return reply.readInt32();
86    }
87
88    status_t stop()
89    {
90        Parcel data, reply;
91        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
92        remote()->transact(STOP, data, &reply);
93        return reply.readInt32();
94    }
95
96    status_t isPlaying(bool* state)
97    {
98        Parcel data, reply;
99        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
100        remote()->transact(IS_PLAYING, data, &reply);
101        *state = reply.readInt32();
102        return reply.readInt32();
103    }
104
105    status_t pause()
106    {
107        Parcel data, reply;
108        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
109        remote()->transact(PAUSE, data, &reply);
110        return reply.readInt32();
111    }
112
113    status_t seekTo(int msec)
114    {
115        Parcel data, reply;
116        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
117        data.writeInt32(msec);
118        remote()->transact(SEEK_TO, data, &reply);
119        return reply.readInt32();
120    }
121
122    status_t getCurrentPosition(int* msec)
123    {
124        Parcel data, reply;
125        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
126        remote()->transact(GET_CURRENT_POSITION, data, &reply);
127        *msec = reply.readInt32();
128        return reply.readInt32();
129    }
130
131    status_t getDuration(int* msec)
132    {
133        Parcel data, reply;
134        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
135        remote()->transact(GET_DURATION, data, &reply);
136        *msec = reply.readInt32();
137        return reply.readInt32();
138    }
139
140    status_t reset()
141    {
142        Parcel data, reply;
143        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
144        remote()->transact(RESET, data, &reply);
145        return reply.readInt32();
146    }
147
148    status_t setAudioStreamType(int type)
149    {
150        Parcel data, reply;
151        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
152        data.writeInt32(type);
153        remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
154        return reply.readInt32();
155    }
156
157    status_t setLooping(int loop)
158    {
159        Parcel data, reply;
160        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
161        data.writeInt32(loop);
162        remote()->transact(SET_LOOPING, data, &reply);
163        return reply.readInt32();
164    }
165
166    status_t setVolume(float leftVolume, float rightVolume)
167    {
168        Parcel data, reply;
169        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
170        data.writeFloat(leftVolume);
171        data.writeFloat(rightVolume);
172        remote()->transact(SET_VOLUME, data, &reply);
173        return reply.readInt32();
174    }
175
176    status_t invoke(const Parcel& request, Parcel *reply)
177    { // Avoid doing any extra copy. The interface descriptor should
178      // have been set by MediaPlayer.java.
179        status_t retcode = remote()->transact(INVOKE, request, reply);
180        return retcode;
181    }
182
183    status_t setMetadataFilter(const Parcel& request)
184    {
185        Parcel reply;
186        // Avoid doing any extra copy of the request. The interface
187        // descriptor should have been set by MediaPlayer.java.
188        remote()->transact(SET_METADATA_FILTER, request, &reply);
189        return reply.readInt32();
190    }
191};
192
193IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
194
195// ----------------------------------------------------------------------
196
197status_t BnMediaPlayer::onTransact(
198    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
199{
200    switch(code) {
201        case DISCONNECT: {
202            CHECK_INTERFACE(IMediaPlayer, data, reply);
203            disconnect();
204            return NO_ERROR;
205        } break;
206        case SET_VIDEO_SURFACE: {
207            CHECK_INTERFACE(IMediaPlayer, data, reply);
208            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
209            reply->writeInt32(setVideoSurface(surface));
210            return NO_ERROR;
211        } break;
212        case PREPARE_ASYNC: {
213            CHECK_INTERFACE(IMediaPlayer, data, reply);
214            reply->writeInt32(prepareAsync());
215            return NO_ERROR;
216        } break;
217        case START: {
218            CHECK_INTERFACE(IMediaPlayer, data, reply);
219            reply->writeInt32(start());
220            return NO_ERROR;
221        } break;
222        case STOP: {
223            CHECK_INTERFACE(IMediaPlayer, data, reply);
224            reply->writeInt32(stop());
225            return NO_ERROR;
226        } break;
227        case IS_PLAYING: {
228            CHECK_INTERFACE(IMediaPlayer, data, reply);
229            bool state;
230            status_t ret = isPlaying(&state);
231            reply->writeInt32(state);
232            reply->writeInt32(ret);
233            return NO_ERROR;
234        } break;
235        case PAUSE: {
236            CHECK_INTERFACE(IMediaPlayer, data, reply);
237            reply->writeInt32(pause());
238            return NO_ERROR;
239        } break;
240        case SEEK_TO: {
241            CHECK_INTERFACE(IMediaPlayer, data, reply);
242            reply->writeInt32(seekTo(data.readInt32()));
243            return NO_ERROR;
244        } break;
245        case GET_CURRENT_POSITION: {
246            CHECK_INTERFACE(IMediaPlayer, data, reply);
247            int msec;
248            status_t ret = getCurrentPosition(&msec);
249            reply->writeInt32(msec);
250            reply->writeInt32(ret);
251            return NO_ERROR;
252        } break;
253        case GET_DURATION: {
254            CHECK_INTERFACE(IMediaPlayer, data, reply);
255            int msec;
256            status_t ret = getDuration(&msec);
257            reply->writeInt32(msec);
258            reply->writeInt32(ret);
259            return NO_ERROR;
260        } break;
261        case RESET: {
262            CHECK_INTERFACE(IMediaPlayer, data, reply);
263            reply->writeInt32(reset());
264            return NO_ERROR;
265        } break;
266        case SET_AUDIO_STREAM_TYPE: {
267            CHECK_INTERFACE(IMediaPlayer, data, reply);
268            reply->writeInt32(setAudioStreamType(data.readInt32()));
269            return NO_ERROR;
270        } break;
271        case SET_LOOPING: {
272            CHECK_INTERFACE(IMediaPlayer, data, reply);
273            reply->writeInt32(setLooping(data.readInt32()));
274            return NO_ERROR;
275        } break;
276        case SET_VOLUME: {
277            CHECK_INTERFACE(IMediaPlayer, data, reply);
278            reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
279            return NO_ERROR;
280        } break;
281        case INVOKE: {
282            CHECK_INTERFACE(IMediaPlayer, data, reply);
283            invoke(data, reply);
284            return NO_ERROR;
285        } break;
286        case SET_METADATA_FILTER: {
287            CHECK_INTERFACE(IMediaPlayer, data, reply);
288            reply->writeInt32(setMetadataFilter(data));
289            return NO_ERROR;
290        } break;
291        default:
292            return BBinder::onTransact(code, data, reply, flags);
293    }
294}
295
296// ----------------------------------------------------------------------------
297
298}; // namespace android
299