blob: 9dfdcb0ee3b922fead20ce09e1727ceffada4027 [file] [log] [blame]
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001/*
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
Mathias Agopian75624082009-05-19 19:08:10 -070021#include <binder/Parcel.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080022
23#include <media/IMediaPlayer.h>
Mathias Agopian3cf61352010-02-09 17:46:37 -080024#include <surfaceflinger/ISurface.h>
Andreas Huber5daeb122010-08-16 08:49:37 -070025#include <surfaceflinger/Surface.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080026
27namespace android {
28
29enum {
30 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
31 SET_VIDEO_SURFACE,
Andreas Huber5daeb122010-08-16 08:49:37 -070032 SET_VIDEO_ISURFACE,
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080033 PREPARE_ASYNC,
34 START,
35 STOP,
36 IS_PLAYING,
37 PAUSE,
38 SEEK_TO,
39 GET_CURRENT_POSITION,
40 GET_DURATION,
41 RESET,
42 SET_AUDIO_STREAM_TYPE,
43 SET_LOOPING,
Nicolas Catania1d187f12009-05-12 23:25:55 -070044 SET_VOLUME,
45 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070046 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070047 GET_METADATA,
Andreas Huber4e92c7e2010-02-12 12:35:58 -080048 SUSPEND,
49 RESUME,
Eric Laurent2beeb502010-07-16 07:43:46 -070050 SET_AUX_EFFECT_SEND_LEVEL,
51 ATTACH_AUX_EFFECT
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080052};
53
54class BpMediaPlayer: public BpInterface<IMediaPlayer>
55{
56public:
57 BpMediaPlayer(const sp<IBinder>& impl)
58 : BpInterface<IMediaPlayer>(impl)
59 {
60 }
61
62 // disconnect from media player service
63 void disconnect()
64 {
65 Parcel data, reply;
66 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
67 remote()->transact(DISCONNECT, data, &reply);
68 }
69
Andreas Huber5daeb122010-08-16 08:49:37 -070070 status_t setVideoISurface(const sp<ISurface>& surface)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080071 {
72 Parcel data, reply;
73 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
74 data.writeStrongBinder(surface->asBinder());
Andreas Huber5daeb122010-08-16 08:49:37 -070075 remote()->transact(SET_VIDEO_ISURFACE, data, &reply);
76 return reply.readInt32();
77 }
78
79 status_t setVideoSurface(const sp<Surface>& surface)
80 {
81 Parcel data, reply;
82 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
83 Surface::writeToParcel(surface, &data);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080084 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
85 return reply.readInt32();
86 }
87
88 status_t prepareAsync()
89 {
90 Parcel data, reply;
91 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
92 remote()->transact(PREPARE_ASYNC, data, &reply);
93 return reply.readInt32();
94 }
95
96 status_t start()
97 {
98 Parcel data, reply;
99 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
100 remote()->transact(START, data, &reply);
101 return reply.readInt32();
102 }
103
104 status_t stop()
105 {
106 Parcel data, reply;
107 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
108 remote()->transact(STOP, data, &reply);
109 return reply.readInt32();
110 }
111
112 status_t isPlaying(bool* state)
113 {
114 Parcel data, reply;
115 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
116 remote()->transact(IS_PLAYING, data, &reply);
117 *state = reply.readInt32();
118 return reply.readInt32();
119 }
120
121 status_t pause()
122 {
123 Parcel data, reply;
124 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
125 remote()->transact(PAUSE, data, &reply);
126 return reply.readInt32();
127 }
128
129 status_t seekTo(int msec)
130 {
131 Parcel data, reply;
132 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
133 data.writeInt32(msec);
134 remote()->transact(SEEK_TO, data, &reply);
135 return reply.readInt32();
136 }
137
138 status_t getCurrentPosition(int* msec)
139 {
140 Parcel data, reply;
141 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
142 remote()->transact(GET_CURRENT_POSITION, data, &reply);
143 *msec = reply.readInt32();
144 return reply.readInt32();
145 }
146
147 status_t getDuration(int* msec)
148 {
149 Parcel data, reply;
150 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
151 remote()->transact(GET_DURATION, data, &reply);
152 *msec = reply.readInt32();
153 return reply.readInt32();
154 }
155
156 status_t reset()
157 {
158 Parcel data, reply;
159 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
160 remote()->transact(RESET, data, &reply);
161 return reply.readInt32();
162 }
163
164 status_t setAudioStreamType(int type)
165 {
166 Parcel data, reply;
167 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
168 data.writeInt32(type);
169 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
170 return reply.readInt32();
171 }
172
173 status_t setLooping(int loop)
174 {
175 Parcel data, reply;
176 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
177 data.writeInt32(loop);
178 remote()->transact(SET_LOOPING, data, &reply);
179 return reply.readInt32();
180 }
181
182 status_t setVolume(float leftVolume, float rightVolume)
183 {
184 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700185 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800186 data.writeFloat(leftVolume);
187 data.writeFloat(rightVolume);
188 remote()->transact(SET_VOLUME, data, &reply);
189 return reply.readInt32();
190 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700191
192 status_t invoke(const Parcel& request, Parcel *reply)
193 { // Avoid doing any extra copy. The interface descriptor should
194 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700195 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700196 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700197
198 status_t setMetadataFilter(const Parcel& request)
199 {
200 Parcel reply;
201 // Avoid doing any extra copy of the request. The interface
202 // descriptor should have been set by MediaPlayer.java.
203 remote()->transact(SET_METADATA_FILTER, request, &reply);
204 return reply.readInt32();
205 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700206
207 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
208 {
209 Parcel request;
210 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
211 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
212 request.writeInt32(update_only);
213 request.writeInt32(apply_filter);
214 remote()->transact(GET_METADATA, request, reply);
215 return reply->readInt32();
216 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800217
218 status_t suspend() {
219 Parcel request;
220 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
221
222 Parcel reply;
223 remote()->transact(SUSPEND, request, &reply);
224
225 return reply.readInt32();
226 }
227
228 status_t resume() {
229 Parcel request;
230 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
231
232 Parcel reply;
233 remote()->transact(RESUME, request, &reply);
234
235 return reply.readInt32();
236 }
Eric Laurent2beeb502010-07-16 07:43:46 -0700237
238 status_t setAuxEffectSendLevel(float level)
239 {
240 Parcel data, reply;
241 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
242 data.writeFloat(level);
243 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
244 return reply.readInt32();
245 }
246
247 status_t attachAuxEffect(int effectId)
248 {
249 Parcel data, reply;
250 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
251 data.writeInt32(effectId);
252 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
253 return reply.readInt32();
254 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800255};
256
niko56f0cc52009-06-22 08:49:52 -0700257IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800258
259// ----------------------------------------------------------------------
260
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800261status_t BnMediaPlayer::onTransact(
262 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
263{
264 switch(code) {
265 case DISCONNECT: {
266 CHECK_INTERFACE(IMediaPlayer, data, reply);
267 disconnect();
268 return NO_ERROR;
269 } break;
Andreas Huber5daeb122010-08-16 08:49:37 -0700270 case SET_VIDEO_ISURFACE: {
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800271 CHECK_INTERFACE(IMediaPlayer, data, reply);
272 sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
Andreas Huber5daeb122010-08-16 08:49:37 -0700273 reply->writeInt32(setVideoISurface(surface));
274 return NO_ERROR;
275 } break;
276 case SET_VIDEO_SURFACE: {
277 CHECK_INTERFACE(IMediaPlayer, data, reply);
278 sp<Surface> surface = Surface::readFromParcel(data);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800279 reply->writeInt32(setVideoSurface(surface));
280 return NO_ERROR;
281 } break;
282 case PREPARE_ASYNC: {
283 CHECK_INTERFACE(IMediaPlayer, data, reply);
284 reply->writeInt32(prepareAsync());
285 return NO_ERROR;
286 } break;
287 case START: {
288 CHECK_INTERFACE(IMediaPlayer, data, reply);
289 reply->writeInt32(start());
290 return NO_ERROR;
291 } break;
292 case STOP: {
293 CHECK_INTERFACE(IMediaPlayer, data, reply);
294 reply->writeInt32(stop());
295 return NO_ERROR;
296 } break;
297 case IS_PLAYING: {
298 CHECK_INTERFACE(IMediaPlayer, data, reply);
299 bool state;
300 status_t ret = isPlaying(&state);
301 reply->writeInt32(state);
302 reply->writeInt32(ret);
303 return NO_ERROR;
304 } break;
305 case PAUSE: {
306 CHECK_INTERFACE(IMediaPlayer, data, reply);
307 reply->writeInt32(pause());
308 return NO_ERROR;
309 } break;
310 case SEEK_TO: {
311 CHECK_INTERFACE(IMediaPlayer, data, reply);
312 reply->writeInt32(seekTo(data.readInt32()));
313 return NO_ERROR;
314 } break;
315 case GET_CURRENT_POSITION: {
316 CHECK_INTERFACE(IMediaPlayer, data, reply);
317 int msec;
318 status_t ret = getCurrentPosition(&msec);
319 reply->writeInt32(msec);
320 reply->writeInt32(ret);
321 return NO_ERROR;
322 } break;
323 case GET_DURATION: {
324 CHECK_INTERFACE(IMediaPlayer, data, reply);
325 int msec;
326 status_t ret = getDuration(&msec);
327 reply->writeInt32(msec);
328 reply->writeInt32(ret);
329 return NO_ERROR;
330 } break;
331 case RESET: {
332 CHECK_INTERFACE(IMediaPlayer, data, reply);
333 reply->writeInt32(reset());
334 return NO_ERROR;
335 } break;
336 case SET_AUDIO_STREAM_TYPE: {
337 CHECK_INTERFACE(IMediaPlayer, data, reply);
338 reply->writeInt32(setAudioStreamType(data.readInt32()));
339 return NO_ERROR;
340 } break;
341 case SET_LOOPING: {
342 CHECK_INTERFACE(IMediaPlayer, data, reply);
343 reply->writeInt32(setLooping(data.readInt32()));
344 return NO_ERROR;
345 } break;
346 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700347 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800348 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
349 return NO_ERROR;
350 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700351 case INVOKE: {
352 CHECK_INTERFACE(IMediaPlayer, data, reply);
353 invoke(data, reply);
354 return NO_ERROR;
355 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700356 case SET_METADATA_FILTER: {
357 CHECK_INTERFACE(IMediaPlayer, data, reply);
358 reply->writeInt32(setMetadataFilter(data));
359 return NO_ERROR;
360 } break;
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800361 case SUSPEND: {
362 CHECK_INTERFACE(IMediaPlayer, data, reply);
363 reply->writeInt32(suspend());
364 return NO_ERROR;
365 } break;
366 case RESUME: {
367 CHECK_INTERFACE(IMediaPlayer, data, reply);
368 reply->writeInt32(resume());
369 return NO_ERROR;
370 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700371 case GET_METADATA: {
372 CHECK_INTERFACE(IMediaPlayer, data, reply);
373 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
374 reply->setDataPosition(0);
375 reply->writeInt32(retcode);
376 reply->setDataPosition(0);
377 return NO_ERROR;
378 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700379 case SET_AUX_EFFECT_SEND_LEVEL: {
380 CHECK_INTERFACE(IMediaPlayer, data, reply);
381 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
382 return NO_ERROR;
383 } break;
384 case ATTACH_AUX_EFFECT: {
385 CHECK_INTERFACE(IMediaPlayer, data, reply);
386 reply->writeInt32(attachAuxEffect(data.readInt32()));
387 return NO_ERROR;
388 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800389 default:
390 return BBinder::onTransact(code, data, reply, flags);
391 }
392}
393
394// ----------------------------------------------------------------------------
395
396}; // namespace android