blob: 0f55b19dc82e925596559276b7b53bb54c120cb3 [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>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080025
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,
Nicolas Catania1d187f12009-05-12 23:25:55 -070042 SET_VOLUME,
43 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070044 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070045 GET_METADATA,
Andreas Huber4e92c7e2010-02-12 12:35:58 -080046 SUSPEND,
47 RESUME,
Eric Laurent2beeb502010-07-16 07:43:46 -070048 SET_AUX_EFFECT_SEND_LEVEL,
49 ATTACH_AUX_EFFECT
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080050};
51
52class BpMediaPlayer: public BpInterface<IMediaPlayer>
53{
54public:
55 BpMediaPlayer(const sp<IBinder>& impl)
56 : BpInterface<IMediaPlayer>(impl)
57 {
58 }
59
60 // disconnect from media player service
61 void disconnect()
62 {
63 Parcel data, reply;
64 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
65 remote()->transact(DISCONNECT, data, &reply);
66 }
67
68 status_t setVideoSurface(const sp<ISurface>& surface)
69 {
70 Parcel data, reply;
71 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
72 data.writeStrongBinder(surface->asBinder());
73 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
74 return reply.readInt32();
75 }
76
77 status_t prepareAsync()
78 {
79 Parcel data, reply;
80 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
81 remote()->transact(PREPARE_ASYNC, data, &reply);
82 return reply.readInt32();
83 }
84
85 status_t start()
86 {
87 Parcel data, reply;
88 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
89 remote()->transact(START, data, &reply);
90 return reply.readInt32();
91 }
92
93 status_t stop()
94 {
95 Parcel data, reply;
96 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
97 remote()->transact(STOP, data, &reply);
98 return reply.readInt32();
99 }
100
101 status_t isPlaying(bool* state)
102 {
103 Parcel data, reply;
104 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
105 remote()->transact(IS_PLAYING, data, &reply);
106 *state = reply.readInt32();
107 return reply.readInt32();
108 }
109
110 status_t pause()
111 {
112 Parcel data, reply;
113 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
114 remote()->transact(PAUSE, data, &reply);
115 return reply.readInt32();
116 }
117
118 status_t seekTo(int msec)
119 {
120 Parcel data, reply;
121 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
122 data.writeInt32(msec);
123 remote()->transact(SEEK_TO, data, &reply);
124 return reply.readInt32();
125 }
126
127 status_t getCurrentPosition(int* msec)
128 {
129 Parcel data, reply;
130 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
131 remote()->transact(GET_CURRENT_POSITION, data, &reply);
132 *msec = reply.readInt32();
133 return reply.readInt32();
134 }
135
136 status_t getDuration(int* msec)
137 {
138 Parcel data, reply;
139 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
140 remote()->transact(GET_DURATION, data, &reply);
141 *msec = reply.readInt32();
142 return reply.readInt32();
143 }
144
145 status_t reset()
146 {
147 Parcel data, reply;
148 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
149 remote()->transact(RESET, data, &reply);
150 return reply.readInt32();
151 }
152
153 status_t setAudioStreamType(int type)
154 {
155 Parcel data, reply;
156 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
157 data.writeInt32(type);
158 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
159 return reply.readInt32();
160 }
161
162 status_t setLooping(int loop)
163 {
164 Parcel data, reply;
165 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
166 data.writeInt32(loop);
167 remote()->transact(SET_LOOPING, data, &reply);
168 return reply.readInt32();
169 }
170
171 status_t setVolume(float leftVolume, float rightVolume)
172 {
173 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700174 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800175 data.writeFloat(leftVolume);
176 data.writeFloat(rightVolume);
177 remote()->transact(SET_VOLUME, data, &reply);
178 return reply.readInt32();
179 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700180
181 status_t invoke(const Parcel& request, Parcel *reply)
182 { // Avoid doing any extra copy. The interface descriptor should
183 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700184 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700185 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700186
187 status_t setMetadataFilter(const Parcel& request)
188 {
189 Parcel reply;
190 // Avoid doing any extra copy of the request. The interface
191 // descriptor should have been set by MediaPlayer.java.
192 remote()->transact(SET_METADATA_FILTER, request, &reply);
193 return reply.readInt32();
194 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700195
196 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
197 {
198 Parcel request;
199 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
200 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
201 request.writeInt32(update_only);
202 request.writeInt32(apply_filter);
203 remote()->transact(GET_METADATA, request, reply);
204 return reply->readInt32();
205 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800206
207 status_t suspend() {
208 Parcel request;
209 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
210
211 Parcel reply;
212 remote()->transact(SUSPEND, request, &reply);
213
214 return reply.readInt32();
215 }
216
217 status_t resume() {
218 Parcel request;
219 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
220
221 Parcel reply;
222 remote()->transact(RESUME, request, &reply);
223
224 return reply.readInt32();
225 }
Eric Laurent2beeb502010-07-16 07:43:46 -0700226
227 status_t setAuxEffectSendLevel(float level)
228 {
229 Parcel data, reply;
230 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
231 data.writeFloat(level);
232 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
233 return reply.readInt32();
234 }
235
236 status_t attachAuxEffect(int effectId)
237 {
238 Parcel data, reply;
239 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
240 data.writeInt32(effectId);
241 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
242 return reply.readInt32();
243 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800244};
245
niko56f0cc52009-06-22 08:49:52 -0700246IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800247
248// ----------------------------------------------------------------------
249
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800250status_t BnMediaPlayer::onTransact(
251 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
252{
253 switch(code) {
254 case DISCONNECT: {
255 CHECK_INTERFACE(IMediaPlayer, data, reply);
256 disconnect();
257 return NO_ERROR;
258 } break;
259 case SET_VIDEO_SURFACE: {
260 CHECK_INTERFACE(IMediaPlayer, data, reply);
261 sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
262 reply->writeInt32(setVideoSurface(surface));
263 return NO_ERROR;
264 } break;
265 case PREPARE_ASYNC: {
266 CHECK_INTERFACE(IMediaPlayer, data, reply);
267 reply->writeInt32(prepareAsync());
268 return NO_ERROR;
269 } break;
270 case START: {
271 CHECK_INTERFACE(IMediaPlayer, data, reply);
272 reply->writeInt32(start());
273 return NO_ERROR;
274 } break;
275 case STOP: {
276 CHECK_INTERFACE(IMediaPlayer, data, reply);
277 reply->writeInt32(stop());
278 return NO_ERROR;
279 } break;
280 case IS_PLAYING: {
281 CHECK_INTERFACE(IMediaPlayer, data, reply);
282 bool state;
283 status_t ret = isPlaying(&state);
284 reply->writeInt32(state);
285 reply->writeInt32(ret);
286 return NO_ERROR;
287 } break;
288 case PAUSE: {
289 CHECK_INTERFACE(IMediaPlayer, data, reply);
290 reply->writeInt32(pause());
291 return NO_ERROR;
292 } break;
293 case SEEK_TO: {
294 CHECK_INTERFACE(IMediaPlayer, data, reply);
295 reply->writeInt32(seekTo(data.readInt32()));
296 return NO_ERROR;
297 } break;
298 case GET_CURRENT_POSITION: {
299 CHECK_INTERFACE(IMediaPlayer, data, reply);
300 int msec;
301 status_t ret = getCurrentPosition(&msec);
302 reply->writeInt32(msec);
303 reply->writeInt32(ret);
304 return NO_ERROR;
305 } break;
306 case GET_DURATION: {
307 CHECK_INTERFACE(IMediaPlayer, data, reply);
308 int msec;
309 status_t ret = getDuration(&msec);
310 reply->writeInt32(msec);
311 reply->writeInt32(ret);
312 return NO_ERROR;
313 } break;
314 case RESET: {
315 CHECK_INTERFACE(IMediaPlayer, data, reply);
316 reply->writeInt32(reset());
317 return NO_ERROR;
318 } break;
319 case SET_AUDIO_STREAM_TYPE: {
320 CHECK_INTERFACE(IMediaPlayer, data, reply);
321 reply->writeInt32(setAudioStreamType(data.readInt32()));
322 return NO_ERROR;
323 } break;
324 case SET_LOOPING: {
325 CHECK_INTERFACE(IMediaPlayer, data, reply);
326 reply->writeInt32(setLooping(data.readInt32()));
327 return NO_ERROR;
328 } break;
329 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700330 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800331 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
332 return NO_ERROR;
333 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700334 case INVOKE: {
335 CHECK_INTERFACE(IMediaPlayer, data, reply);
336 invoke(data, reply);
337 return NO_ERROR;
338 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700339 case SET_METADATA_FILTER: {
340 CHECK_INTERFACE(IMediaPlayer, data, reply);
341 reply->writeInt32(setMetadataFilter(data));
342 return NO_ERROR;
343 } break;
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800344 case SUSPEND: {
345 CHECK_INTERFACE(IMediaPlayer, data, reply);
346 reply->writeInt32(suspend());
347 return NO_ERROR;
348 } break;
349 case RESUME: {
350 CHECK_INTERFACE(IMediaPlayer, data, reply);
351 reply->writeInt32(resume());
352 return NO_ERROR;
353 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700354 case GET_METADATA: {
355 CHECK_INTERFACE(IMediaPlayer, data, reply);
356 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
357 reply->setDataPosition(0);
358 reply->writeInt32(retcode);
359 reply->setDataPosition(0);
360 return NO_ERROR;
361 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700362 case SET_AUX_EFFECT_SEND_LEVEL: {
363 CHECK_INTERFACE(IMediaPlayer, data, reply);
364 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
365 return NO_ERROR;
366 } break;
367 case ATTACH_AUX_EFFECT: {
368 CHECK_INTERFACE(IMediaPlayer, data, reply);
369 reply->writeInt32(attachAuxEffect(data.readInt32()));
370 return NO_ERROR;
371 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800372 default:
373 return BBinder::onTransact(code, data, reply, flags);
374 }
375}
376
377// ----------------------------------------------------------------------------
378
379}; // namespace android