blob: c287c0af21033dce470f98b2e2e6e1ba42c3f0cb [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,
32 PREPARE_ASYNC,
33 START,
34 STOP,
35 IS_PLAYING,
36 PAUSE,
37 SEEK_TO,
38 GET_CURRENT_POSITION,
39 GET_DURATION,
40 RESET,
41 SET_AUDIO_STREAM_TYPE,
42 SET_LOOPING,
Nicolas Catania1d187f12009-05-12 23:25:55 -070043 SET_VOLUME,
44 INVOKE,
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -070045 SET_METADATA_FILTER,
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -070046 GET_METADATA,
Eric Laurent2beeb502010-07-16 07:43:46 -070047 SET_AUX_EFFECT_SEND_LEVEL,
48 ATTACH_AUX_EFFECT
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080049};
50
51class BpMediaPlayer: public BpInterface<IMediaPlayer>
52{
53public:
54 BpMediaPlayer(const sp<IBinder>& impl)
55 : BpInterface<IMediaPlayer>(impl)
56 {
57 }
58
59 // disconnect from media player service
60 void disconnect()
61 {
62 Parcel data, reply;
63 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
64 remote()->transact(DISCONNECT, data, &reply);
65 }
66
Andreas Huber5daeb122010-08-16 08:49:37 -070067 status_t setVideoSurface(const sp<Surface>& surface)
68 {
69 Parcel data, reply;
70 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
71 Surface::writeToParcel(surface, &data);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080072 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
73 return reply.readInt32();
74 }
75
76 status_t prepareAsync()
77 {
78 Parcel data, reply;
79 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
80 remote()->transact(PREPARE_ASYNC, data, &reply);
81 return reply.readInt32();
82 }
83
84 status_t start()
85 {
86 Parcel data, reply;
87 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
88 remote()->transact(START, data, &reply);
89 return reply.readInt32();
90 }
91
92 status_t stop()
93 {
94 Parcel data, reply;
95 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
96 remote()->transact(STOP, data, &reply);
97 return reply.readInt32();
98 }
99
100 status_t isPlaying(bool* state)
101 {
102 Parcel data, reply;
103 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
104 remote()->transact(IS_PLAYING, data, &reply);
105 *state = reply.readInt32();
106 return reply.readInt32();
107 }
108
109 status_t pause()
110 {
111 Parcel data, reply;
112 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
113 remote()->transact(PAUSE, data, &reply);
114 return reply.readInt32();
115 }
116
117 status_t seekTo(int msec)
118 {
119 Parcel data, reply;
120 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
121 data.writeInt32(msec);
122 remote()->transact(SEEK_TO, data, &reply);
123 return reply.readInt32();
124 }
125
126 status_t getCurrentPosition(int* msec)
127 {
128 Parcel data, reply;
129 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
130 remote()->transact(GET_CURRENT_POSITION, data, &reply);
131 *msec = reply.readInt32();
132 return reply.readInt32();
133 }
134
135 status_t getDuration(int* msec)
136 {
137 Parcel data, reply;
138 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
139 remote()->transact(GET_DURATION, data, &reply);
140 *msec = reply.readInt32();
141 return reply.readInt32();
142 }
143
144 status_t reset()
145 {
146 Parcel data, reply;
147 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
148 remote()->transact(RESET, data, &reply);
149 return reply.readInt32();
150 }
151
152 status_t setAudioStreamType(int type)
153 {
154 Parcel data, reply;
155 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
156 data.writeInt32(type);
157 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
158 return reply.readInt32();
159 }
160
161 status_t setLooping(int loop)
162 {
163 Parcel data, reply;
164 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
165 data.writeInt32(loop);
166 remote()->transact(SET_LOOPING, data, &reply);
167 return reply.readInt32();
168 }
169
170 status_t setVolume(float leftVolume, float rightVolume)
171 {
172 Parcel data, reply;
Dave Sparks172fb9a2009-05-26 14:39:29 -0700173 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800174 data.writeFloat(leftVolume);
175 data.writeFloat(rightVolume);
176 remote()->transact(SET_VOLUME, data, &reply);
177 return reply.readInt32();
178 }
Nicolas Catania1d187f12009-05-12 23:25:55 -0700179
180 status_t invoke(const Parcel& request, Parcel *reply)
181 { // Avoid doing any extra copy. The interface descriptor should
182 // have been set by MediaPlayer.java.
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700183 return remote()->transact(INVOKE, request, reply);
Nicolas Catania1d187f12009-05-12 23:25:55 -0700184 }
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700185
186 status_t setMetadataFilter(const Parcel& request)
187 {
188 Parcel reply;
189 // Avoid doing any extra copy of the request. The interface
190 // descriptor should have been set by MediaPlayer.java.
191 remote()->transact(SET_METADATA_FILTER, request, &reply);
192 return reply.readInt32();
193 }
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700194
195 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
196 {
197 Parcel request;
198 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
199 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
200 request.writeInt32(update_only);
201 request.writeInt32(apply_filter);
202 remote()->transact(GET_METADATA, request, reply);
203 return reply->readInt32();
204 }
Andreas Huber4e92c7e2010-02-12 12:35:58 -0800205
Eric Laurent2beeb502010-07-16 07:43:46 -0700206 status_t setAuxEffectSendLevel(float level)
207 {
208 Parcel data, reply;
209 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
210 data.writeFloat(level);
211 remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
212 return reply.readInt32();
213 }
214
215 status_t attachAuxEffect(int effectId)
216 {
217 Parcel data, reply;
218 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
219 data.writeInt32(effectId);
220 remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
221 return reply.readInt32();
222 }
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800223};
224
niko56f0cc52009-06-22 08:49:52 -0700225IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800226
227// ----------------------------------------------------------------------
228
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800229status_t BnMediaPlayer::onTransact(
230 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
231{
232 switch(code) {
233 case DISCONNECT: {
234 CHECK_INTERFACE(IMediaPlayer, data, reply);
235 disconnect();
236 return NO_ERROR;
237 } break;
Andreas Huber5daeb122010-08-16 08:49:37 -0700238 case SET_VIDEO_SURFACE: {
239 CHECK_INTERFACE(IMediaPlayer, data, reply);
240 sp<Surface> surface = Surface::readFromParcel(data);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800241 reply->writeInt32(setVideoSurface(surface));
242 return NO_ERROR;
243 } break;
244 case PREPARE_ASYNC: {
245 CHECK_INTERFACE(IMediaPlayer, data, reply);
246 reply->writeInt32(prepareAsync());
247 return NO_ERROR;
248 } break;
249 case START: {
250 CHECK_INTERFACE(IMediaPlayer, data, reply);
251 reply->writeInt32(start());
252 return NO_ERROR;
253 } break;
254 case STOP: {
255 CHECK_INTERFACE(IMediaPlayer, data, reply);
256 reply->writeInt32(stop());
257 return NO_ERROR;
258 } break;
259 case IS_PLAYING: {
260 CHECK_INTERFACE(IMediaPlayer, data, reply);
261 bool state;
262 status_t ret = isPlaying(&state);
263 reply->writeInt32(state);
264 reply->writeInt32(ret);
265 return NO_ERROR;
266 } break;
267 case PAUSE: {
268 CHECK_INTERFACE(IMediaPlayer, data, reply);
269 reply->writeInt32(pause());
270 return NO_ERROR;
271 } break;
272 case SEEK_TO: {
273 CHECK_INTERFACE(IMediaPlayer, data, reply);
274 reply->writeInt32(seekTo(data.readInt32()));
275 return NO_ERROR;
276 } break;
277 case GET_CURRENT_POSITION: {
278 CHECK_INTERFACE(IMediaPlayer, data, reply);
279 int msec;
280 status_t ret = getCurrentPosition(&msec);
281 reply->writeInt32(msec);
282 reply->writeInt32(ret);
283 return NO_ERROR;
284 } break;
285 case GET_DURATION: {
286 CHECK_INTERFACE(IMediaPlayer, data, reply);
287 int msec;
288 status_t ret = getDuration(&msec);
289 reply->writeInt32(msec);
290 reply->writeInt32(ret);
291 return NO_ERROR;
292 } break;
293 case RESET: {
294 CHECK_INTERFACE(IMediaPlayer, data, reply);
295 reply->writeInt32(reset());
296 return NO_ERROR;
297 } break;
298 case SET_AUDIO_STREAM_TYPE: {
299 CHECK_INTERFACE(IMediaPlayer, data, reply);
300 reply->writeInt32(setAudioStreamType(data.readInt32()));
301 return NO_ERROR;
302 } break;
303 case SET_LOOPING: {
304 CHECK_INTERFACE(IMediaPlayer, data, reply);
305 reply->writeInt32(setLooping(data.readInt32()));
306 return NO_ERROR;
307 } break;
308 case SET_VOLUME: {
Dave Sparks172fb9a2009-05-26 14:39:29 -0700309 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800310 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
311 return NO_ERROR;
312 } break;
Nicolas Catania1d187f12009-05-12 23:25:55 -0700313 case INVOKE: {
314 CHECK_INTERFACE(IMediaPlayer, data, reply);
315 invoke(data, reply);
316 return NO_ERROR;
317 } break;
Nicolas Cataniaa7e0e8b2009-07-08 08:57:42 -0700318 case SET_METADATA_FILTER: {
319 CHECK_INTERFACE(IMediaPlayer, data, reply);
320 reply->writeInt32(setMetadataFilter(data));
321 return NO_ERROR;
322 } break;
Nicolas Catania8e1b6cc2009-07-09 09:21:33 -0700323 case GET_METADATA: {
324 CHECK_INTERFACE(IMediaPlayer, data, reply);
325 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
326 reply->setDataPosition(0);
327 reply->writeInt32(retcode);
328 reply->setDataPosition(0);
329 return NO_ERROR;
330 } break;
Eric Laurent2beeb502010-07-16 07:43:46 -0700331 case SET_AUX_EFFECT_SEND_LEVEL: {
332 CHECK_INTERFACE(IMediaPlayer, data, reply);
333 reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
334 return NO_ERROR;
335 } break;
336 case ATTACH_AUX_EFFECT: {
337 CHECK_INTERFACE(IMediaPlayer, data, reply);
338 reply->writeInt32(attachAuxEffect(data.readInt32()));
339 return NO_ERROR;
340 } break;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800341 default:
342 return BBinder::onTransact(code, data, reply, flags);
343 }
344}
345
346// ----------------------------------------------------------------------------
347
348}; // namespace android