blob: 8885bd5914e94b1ed9a8a1e0b1f01520cac2bb1f [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,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051};
52
53class BpMediaPlayer: public BpInterface<IMediaPlayer>
54{
55public:
56 BpMediaPlayer(const sp<IBinder>& impl)
57 : BpInterface<IMediaPlayer>(impl)
58 {
59 }
60
61 // disconnect from media player service
62 void disconnect()
63 {
64 Parcel data, reply;
65 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
66 remote()->transact(DISCONNECT, data, &reply);
67 }
68
Glenn Kastencc562a32011-02-08 17:26:17 -080069 // pass the buffered Surface to the media player service
Andreas Hubere3c01832010-08-16 08:49:37 -070070 status_t setVideoSurface(const sp<Surface>& surface)
71 {
72 Parcel data, reply;
73 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
74 Surface::writeToParcel(surface, &data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
76 return reply.readInt32();
77 }
78
Glenn Kastencc562a32011-02-08 17:26:17 -080079 // pass the buffered ISurfaceTexture to the media player service
80 status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
81 {
82 Parcel data, reply;
83 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
84 sp<IBinder> b(surfaceTexture->asBinder());
85 data.writeStrongBinder(b);
86 remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
87 return reply.readInt32();
88 }
89
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 status_t prepareAsync()
91 {
92 Parcel data, reply;
93 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
94 remote()->transact(PREPARE_ASYNC, data, &reply);
95 return reply.readInt32();
96 }
97
98 status_t start()
99 {
100 Parcel data, reply;
101 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
102 remote()->transact(START, data, &reply);
103 return reply.readInt32();
104 }
105
106 status_t stop()
107 {
108 Parcel data, reply;
109 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
110 remote()->transact(STOP, data, &reply);
111 return reply.readInt32();
112 }
113
114 status_t isPlaying(bool* state)
115 {
116 Parcel data, reply;
117 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
118 remote()->transact(IS_PLAYING, data, &reply);
119 *state = reply.readInt32();
120 return reply.readInt32();
121 }
122
123 status_t pause()
124 {
125 Parcel data, reply;
126 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
127 remote()->transact(PAUSE, data, &reply);
128 return reply.readInt32();
129 }
130
131 status_t seekTo(int msec)
132 {
133 Parcel data, reply;
134 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
135 data.writeInt32(msec);
136 remote()->transact(SEEK_TO, data, &reply);
137 return reply.readInt32();
138 }
139
140 status_t getCurrentPosition(int* msec)
141 {
142 Parcel data, reply;
143 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
144 remote()->transact(GET_CURRENT_POSITION, data, &reply);
145 *msec = reply.readInt32();
146 return reply.readInt32();
147 }
148
149 status_t getDuration(int* msec)
150 {
151 Parcel data, reply;
152 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
153 remote()->transact(GET_DURATION, data, &reply);
154 *msec = reply.readInt32();
155 return reply.readInt32();
156 }
157
158 status_t reset()
159 {
160 Parcel data, reply;
161 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
162 remote()->transact(RESET, data, &reply);
163 return reply.readInt32();
164 }
165
166 status_t setAudioStreamType(int type)
167 {
168 Parcel data, reply;
169 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
170 data.writeInt32(type);
171 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
172 return reply.readInt32();
173 }
174
175 status_t setLooping(int loop)
176 {
177 Parcel data, reply;
178 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
179 data.writeInt32(loop);
180 remote()->transact(SET_LOOPING, data, &reply);
181 return reply.readInt32();
182 }
183
184 status_t setVolume(float leftVolume, float rightVolume)
185 {
186 Parcel data, reply;
Dave Sparks81494192009-05-26 14:39:29 -0700187 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 data.writeFloat(leftVolume);
189 data.writeFloat(rightVolume);
190 remote()->transact(SET_VOLUME, data, &reply);
191 return reply.readInt32();
192 }
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700193
194 status_t invoke(const Parcel& request, Parcel *reply)
James Dong4edf1d12011-04-06 18:29:01 -0700195 {
196 // Avoid doing any extra copy. The interface descriptor should
197 // have been set by MediaPlayer.java.
Nicolas Catania5d55c712009-07-09 09:21:33 -0700198 return remote()->transact(INVOKE, request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700199 }
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700200
201 status_t setMetadataFilter(const Parcel& request)
202 {
203 Parcel reply;
204 // Avoid doing any extra copy of the request. The interface
205 // descriptor should have been set by MediaPlayer.java.
206 remote()->transact(SET_METADATA_FILTER, request, &reply);
207 return reply.readInt32();
208 }
Nicolas Catania5d55c712009-07-09 09:21:33 -0700209
210 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
211 {
212 Parcel request;
213 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
214 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
215 request.writeInt32(update_only);
216 request.writeInt32(apply_filter);
217 remote()->transact(GET_METADATA, request, reply);
218 return reply->readInt32();
219 }
Andreas Huberfbb38852010-02-12 12:35:58 -0800220
Eric Laurent7070b362010-07-16 07:43:46 -0700221 status_t setAuxEffectSendLevel(float level)
222 {
223 Parcel data, reply;
224 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
225 data.writeFloat(level);
226 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
227 return reply.readInt32();
228 }
229
230 status_t attachAuxEffect(int effectId)
231 {
232 Parcel data, reply;
233 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
234 data.writeInt32(effectId);
235 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
236 return reply.readInt32();
237 }
Glenn Kastencc562a32011-02-08 17:26:17 -0800238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239};
240
nikodcd810d2009-06-22 08:49:52 -0700241IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242
243// ----------------------------------------------------------------------
244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245status_t BnMediaPlayer::onTransact(
246 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
247{
248 switch(code) {
249 case DISCONNECT: {
250 CHECK_INTERFACE(IMediaPlayer, data, reply);
251 disconnect();
252 return NO_ERROR;
253 } break;
Andreas Hubere3c01832010-08-16 08:49:37 -0700254 case SET_VIDEO_SURFACE: {
255 CHECK_INTERFACE(IMediaPlayer, data, reply);
256 sp<Surface> surface = Surface::readFromParcel(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 reply->writeInt32(setVideoSurface(surface));
258 return NO_ERROR;
259 } break;
Glenn Kastencc562a32011-02-08 17:26:17 -0800260 case SET_VIDEO_SURFACETEXTURE: {
261 CHECK_INTERFACE(IMediaPlayer, data, reply);
262 sp<ISurfaceTexture> surfaceTexture =
263 interface_cast<ISurfaceTexture>(data.readStrongBinder());
264 reply->writeInt32(setVideoSurfaceTexture(surfaceTexture));
265 return NO_ERROR;
266 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 case PREPARE_ASYNC: {
268 CHECK_INTERFACE(IMediaPlayer, data, reply);
269 reply->writeInt32(prepareAsync());
270 return NO_ERROR;
271 } break;
272 case START: {
273 CHECK_INTERFACE(IMediaPlayer, data, reply);
274 reply->writeInt32(start());
275 return NO_ERROR;
276 } break;
277 case STOP: {
278 CHECK_INTERFACE(IMediaPlayer, data, reply);
279 reply->writeInt32(stop());
280 return NO_ERROR;
281 } break;
282 case IS_PLAYING: {
283 CHECK_INTERFACE(IMediaPlayer, data, reply);
284 bool state;
285 status_t ret = isPlaying(&state);
286 reply->writeInt32(state);
287 reply->writeInt32(ret);
288 return NO_ERROR;
289 } break;
290 case PAUSE: {
291 CHECK_INTERFACE(IMediaPlayer, data, reply);
292 reply->writeInt32(pause());
293 return NO_ERROR;
294 } break;
295 case SEEK_TO: {
296 CHECK_INTERFACE(IMediaPlayer, data, reply);
297 reply->writeInt32(seekTo(data.readInt32()));
298 return NO_ERROR;
299 } break;
300 case GET_CURRENT_POSITION: {
301 CHECK_INTERFACE(IMediaPlayer, data, reply);
302 int msec;
303 status_t ret = getCurrentPosition(&msec);
304 reply->writeInt32(msec);
305 reply->writeInt32(ret);
306 return NO_ERROR;
307 } break;
308 case GET_DURATION: {
309 CHECK_INTERFACE(IMediaPlayer, data, reply);
310 int msec;
311 status_t ret = getDuration(&msec);
312 reply->writeInt32(msec);
313 reply->writeInt32(ret);
314 return NO_ERROR;
315 } break;
316 case RESET: {
317 CHECK_INTERFACE(IMediaPlayer, data, reply);
318 reply->writeInt32(reset());
319 return NO_ERROR;
320 } break;
321 case SET_AUDIO_STREAM_TYPE: {
322 CHECK_INTERFACE(IMediaPlayer, data, reply);
323 reply->writeInt32(setAudioStreamType(data.readInt32()));
324 return NO_ERROR;
325 } break;
326 case SET_LOOPING: {
327 CHECK_INTERFACE(IMediaPlayer, data, reply);
328 reply->writeInt32(setLooping(data.readInt32()));
329 return NO_ERROR;
330 } break;
331 case SET_VOLUME: {
Dave Sparks81494192009-05-26 14:39:29 -0700332 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
334 return NO_ERROR;
335 } break;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700336 case INVOKE: {
337 CHECK_INTERFACE(IMediaPlayer, data, reply);
James Dong4edf1d12011-04-06 18:29:01 -0700338 status_t result = invoke(data, reply);
339 return result;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700340 } break;
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700341 case SET_METADATA_FILTER: {
342 CHECK_INTERFACE(IMediaPlayer, data, reply);
343 reply->writeInt32(setMetadataFilter(data));
344 return NO_ERROR;
345 } break;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700346 case GET_METADATA: {
347 CHECK_INTERFACE(IMediaPlayer, data, reply);
348 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
349 reply->setDataPosition(0);
350 reply->writeInt32(retcode);
351 reply->setDataPosition(0);
352 return NO_ERROR;
353 } break;
Eric Laurent7070b362010-07-16 07:43:46 -0700354 case SET_AUX_EFFECT_SEND_LEVEL: {
355 CHECK_INTERFACE(IMediaPlayer, data, reply);
356 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
357 return NO_ERROR;
358 } break;
359 case ATTACH_AUX_EFFECT: {
360 CHECK_INTERFACE(IMediaPlayer, data, reply);
361 reply->writeInt32(attachAuxEffect(data.readInt32()));
362 return NO_ERROR;
363 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 default:
365 return BBinder::onTransact(code, data, reply, flags);
366 }
367}
368
369// ----------------------------------------------------------------------------
370
371}; // namespace android