blob: 76a8a91cc7c979c76190e60191e93b2598e18c25 [file] [log] [blame]
The Android Open Source Project9066cfe2009-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 Agopian07952722009-05-19 19:08:10 -070021#include <binder/Parcel.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
23#include <media/IMediaPlayer.h>
Mathias Agopian000479f2010-02-09 17:46:37 -080024#include <surfaceflinger/ISurface.h>
Andreas Hubere3c01832010-08-16 08:49:37 -070025#include <surfaceflinger/Surface.h>
Glenn Kastencc562a32011-02-08 17:26:17 -080026#include <gui/ISurfaceTexture.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
28namespace android {
29
30enum {
31 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
32 SET_VIDEO_SURFACE,
33 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 Catania20cb94e2009-05-12 23:25:55 -070044 SET_VOLUME,
45 INVOKE,
Nicolas Cataniab2c69392009-07-08 08:57:42 -070046 SET_METADATA_FILTER,
Nicolas Catania5d55c712009-07-09 09:21:33 -070047 GET_METADATA,
Eric Laurent7070b362010-07-16 07:43:46 -070048 SET_AUX_EFFECT_SEND_LEVEL,
Glenn Kastencc562a32011-02-08 17:26:17 -080049 ATTACH_AUX_EFFECT,
50 SET_VIDEO_SURFACETEXTURE,
Gloria Wangd01ec6e2011-04-25 17:28:22 -070051 SET_PARAMETER,
52 GET_PARAMETER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053};
54
55class BpMediaPlayer: public BpInterface<IMediaPlayer>
56{
57public:
58 BpMediaPlayer(const sp<IBinder>& impl)
59 : BpInterface<IMediaPlayer>(impl)
60 {
61 }
62
63 // disconnect from media player service
64 void disconnect()
65 {
66 Parcel data, reply;
67 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
68 remote()->transact(DISCONNECT, data, &reply);
69 }
70
Glenn Kastencc562a32011-02-08 17:26:17 -080071 // pass the buffered Surface to the media player service
Andreas Hubere3c01832010-08-16 08:49:37 -070072 status_t setVideoSurface(const sp<Surface>& surface)
73 {
74 Parcel data, reply;
75 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
76 Surface::writeToParcel(surface, &data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
78 return reply.readInt32();
79 }
80
Glenn Kastencc562a32011-02-08 17:26:17 -080081 // pass the buffered ISurfaceTexture to the media player service
82 status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
83 {
84 Parcel data, reply;
85 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
86 sp<IBinder> b(surfaceTexture->asBinder());
87 data.writeStrongBinder(b);
88 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
89 return reply.readInt32();
90 }
91
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 status_t prepareAsync()
93 {
94 Parcel data, reply;
95 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
96 remote()->transact(PREPARE_ASYNC, data, &reply);
97 return reply.readInt32();
98 }
99
100 status_t start()
101 {
102 Parcel data, reply;
103 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
104 remote()->transact(START, data, &reply);
105 return reply.readInt32();
106 }
107
108 status_t stop()
109 {
110 Parcel data, reply;
111 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
112 remote()->transact(STOP, data, &reply);
113 return reply.readInt32();
114 }
115
116 status_t isPlaying(bool* state)
117 {
118 Parcel data, reply;
119 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
120 remote()->transact(IS_PLAYING, data, &reply);
121 *state = reply.readInt32();
122 return reply.readInt32();
123 }
124
125 status_t pause()
126 {
127 Parcel data, reply;
128 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
129 remote()->transact(PAUSE, data, &reply);
130 return reply.readInt32();
131 }
132
133 status_t seekTo(int msec)
134 {
135 Parcel data, reply;
136 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
137 data.writeInt32(msec);
138 remote()->transact(SEEK_TO, data, &reply);
139 return reply.readInt32();
140 }
141
142 status_t getCurrentPosition(int* msec)
143 {
144 Parcel data, reply;
145 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
146 remote()->transact(GET_CURRENT_POSITION, data, &reply);
147 *msec = reply.readInt32();
148 return reply.readInt32();
149 }
150
151 status_t getDuration(int* msec)
152 {
153 Parcel data, reply;
154 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
155 remote()->transact(GET_DURATION, data, &reply);
156 *msec = reply.readInt32();
157 return reply.readInt32();
158 }
159
160 status_t reset()
161 {
162 Parcel data, reply;
163 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
164 remote()->transact(RESET, data, &reply);
165 return reply.readInt32();
166 }
167
168 status_t setAudioStreamType(int type)
169 {
170 Parcel data, reply;
171 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
172 data.writeInt32(type);
173 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
174 return reply.readInt32();
175 }
176
177 status_t setLooping(int loop)
178 {
179 Parcel data, reply;
180 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
181 data.writeInt32(loop);
182 remote()->transact(SET_LOOPING, data, &reply);
183 return reply.readInt32();
184 }
185
186 status_t setVolume(float leftVolume, float rightVolume)
187 {
188 Parcel data, reply;
Dave Sparks81494192009-05-26 14:39:29 -0700189 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 data.writeFloat(leftVolume);
191 data.writeFloat(rightVolume);
192 remote()->transact(SET_VOLUME, data, &reply);
193 return reply.readInt32();
194 }
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700195
196 status_t invoke(const Parcel& request, Parcel *reply)
James Dong4edf1d12011-04-06 18:29:01 -0700197 {
198 // Avoid doing any extra copy. The interface descriptor should
199 // have been set by MediaPlayer.java.
Nicolas Catania5d55c712009-07-09 09:21:33 -0700200 return remote()->transact(INVOKE, request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700201 }
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700202
203 status_t setMetadataFilter(const Parcel& request)
204 {
205 Parcel reply;
206 // Avoid doing any extra copy of the request. The interface
207 // descriptor should have been set by MediaPlayer.java.
208 remote()->transact(SET_METADATA_FILTER, request, &reply);
209 return reply.readInt32();
210 }
Nicolas Catania5d55c712009-07-09 09:21:33 -0700211
212 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
213 {
214 Parcel request;
215 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
216 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
217 request.writeInt32(update_only);
218 request.writeInt32(apply_filter);
219 remote()->transact(GET_METADATA, request, reply);
220 return reply->readInt32();
221 }
Andreas Huberfbb38852010-02-12 12:35:58 -0800222
Eric Laurent7070b362010-07-16 07:43:46 -0700223 status_t setAuxEffectSendLevel(float level)
224 {
225 Parcel data, reply;
226 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
227 data.writeFloat(level);
228 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
229 return reply.readInt32();
230 }
231
232 status_t attachAuxEffect(int effectId)
233 {
234 Parcel data, reply;
235 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
236 data.writeInt32(effectId);
237 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
238 return reply.readInt32();
239 }
Glenn Kastencc562a32011-02-08 17:26:17 -0800240
Gloria Wangd01ec6e2011-04-25 17:28:22 -0700241 status_t setParameter(int key, const Parcel& request)
242 {
243 Parcel data, reply;
244 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
245 data.writeInt32(key);
246 if (request.dataSize() > 0) {
247 data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize());
248 }
249 remote()->transact(SET_PARAMETER, data, &reply);
250 return reply.readInt32();
251 }
252
253 status_t getParameter(int key, Parcel *reply)
254 {
255 Parcel data;
256 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
257 data.writeInt32(key);
258 return remote()->transact(GET_PARAMETER, data, reply);
259 }
260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261};
262
nikodcd810d2009-06-22 08:49:52 -0700263IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264
265// ----------------------------------------------------------------------
266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267status_t BnMediaPlayer::onTransact(
268 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
269{
270 switch(code) {
271 case DISCONNECT: {
272 CHECK_INTERFACE(IMediaPlayer, data, reply);
273 disconnect();
274 return NO_ERROR;
275 } break;
Andreas Hubere3c01832010-08-16 08:49:37 -0700276 case SET_VIDEO_SURFACE: {
277 CHECK_INTERFACE(IMediaPlayer, data, reply);
278 sp<Surface> surface = Surface::readFromParcel(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 reply->writeInt32(setVideoSurface(surface));
280 return NO_ERROR;
281 } break;
Glenn Kastencc562a32011-02-08 17:26:17 -0800282 case SET_VIDEO_SURFACETEXTURE: {
283 CHECK_INTERFACE(IMediaPlayer, data, reply);
284 sp<ISurfaceTexture> surfaceTexture =
285 interface_cast<ISurfaceTexture>(data.readStrongBinder());
286 reply->writeInt32(setVideoSurfaceTexture(surfaceTexture));
287 return NO_ERROR;
288 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 case PREPARE_ASYNC: {
290 CHECK_INTERFACE(IMediaPlayer, data, reply);
291 reply->writeInt32(prepareAsync());
292 return NO_ERROR;
293 } break;
294 case START: {
295 CHECK_INTERFACE(IMediaPlayer, data, reply);
296 reply->writeInt32(start());
297 return NO_ERROR;
298 } break;
299 case STOP: {
300 CHECK_INTERFACE(IMediaPlayer, data, reply);
301 reply->writeInt32(stop());
302 return NO_ERROR;
303 } break;
304 case IS_PLAYING: {
305 CHECK_INTERFACE(IMediaPlayer, data, reply);
306 bool state;
307 status_t ret = isPlaying(&state);
308 reply->writeInt32(state);
309 reply->writeInt32(ret);
310 return NO_ERROR;
311 } break;
312 case PAUSE: {
313 CHECK_INTERFACE(IMediaPlayer, data, reply);
314 reply->writeInt32(pause());
315 return NO_ERROR;
316 } break;
317 case SEEK_TO: {
318 CHECK_INTERFACE(IMediaPlayer, data, reply);
319 reply->writeInt32(seekTo(data.readInt32()));
320 return NO_ERROR;
321 } break;
322 case GET_CURRENT_POSITION: {
323 CHECK_INTERFACE(IMediaPlayer, data, reply);
324 int msec;
325 status_t ret = getCurrentPosition(&msec);
326 reply->writeInt32(msec);
327 reply->writeInt32(ret);
328 return NO_ERROR;
329 } break;
330 case GET_DURATION: {
331 CHECK_INTERFACE(IMediaPlayer, data, reply);
332 int msec;
333 status_t ret = getDuration(&msec);
334 reply->writeInt32(msec);
335 reply->writeInt32(ret);
336 return NO_ERROR;
337 } break;
338 case RESET: {
339 CHECK_INTERFACE(IMediaPlayer, data, reply);
340 reply->writeInt32(reset());
341 return NO_ERROR;
342 } break;
343 case SET_AUDIO_STREAM_TYPE: {
344 CHECK_INTERFACE(IMediaPlayer, data, reply);
345 reply->writeInt32(setAudioStreamType(data.readInt32()));
346 return NO_ERROR;
347 } break;
348 case SET_LOOPING: {
349 CHECK_INTERFACE(IMediaPlayer, data, reply);
350 reply->writeInt32(setLooping(data.readInt32()));
351 return NO_ERROR;
352 } break;
353 case SET_VOLUME: {
Dave Sparks81494192009-05-26 14:39:29 -0700354 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
356 return NO_ERROR;
357 } break;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700358 case INVOKE: {
359 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong4edf1d12011-04-06 18:29:01 -0700360 status_t result = invoke(data, reply);
361 return result;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700362 } break;
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700363 case SET_METADATA_FILTER: {
364 CHECK_INTERFACE(IMediaPlayer, data, reply);
365 reply->writeInt32(setMetadataFilter(data));
366 return NO_ERROR;
367 } break;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700368 case GET_METADATA: {
369 CHECK_INTERFACE(IMediaPlayer, data, reply);
370 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
371 reply->setDataPosition(0);
372 reply->writeInt32(retcode);
373 reply->setDataPosition(0);
374 return NO_ERROR;
375 } break;
Eric Laurent7070b362010-07-16 07:43:46 -0700376 case SET_AUX_EFFECT_SEND_LEVEL: {
377 CHECK_INTERFACE(IMediaPlayer, data, reply);
378 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
379 return NO_ERROR;
380 } break;
381 case ATTACH_AUX_EFFECT: {
382 CHECK_INTERFACE(IMediaPlayer, data, reply);
383 reply->writeInt32(attachAuxEffect(data.readInt32()));
384 return NO_ERROR;
385 } break;
Gloria Wangd01ec6e2011-04-25 17:28:22 -0700386 case SET_PARAMETER: {
387 CHECK_INTERFACE(IMediaPlayer, data, reply);
388 int key = data.readInt32();
389
390 Parcel request;
391 if (data.dataAvail() > 0) {
392 request.appendFrom(
393 const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
394 }
395 request.setDataPosition(0);
396 reply->writeInt32(setParameter(key, request));
397 return NO_ERROR;
398 } break;
399 case GET_PARAMETER: {
400 CHECK_INTERFACE(IMediaPlayer, data, reply);
401 return getParameter(data.readInt32(), reply);
402 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 default:
404 return BBinder::onTransact(code, data, reply, flags);
405 }
406}
407
408// ----------------------------------------------------------------------------
409
410}; // namespace android