blob: ed792b337693b597e127f119f8aea668762c9713 [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>
The Android Open Source Project9066cfe2009-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 Catania20cb94e2009-05-12 23:25:55 -070042 SET_VOLUME,
43 INVOKE,
Nicolas Cataniab2c69392009-07-08 08:57:42 -070044 SET_METADATA_FILTER,
Nicolas Catania5d55c712009-07-09 09:21:33 -070045 GET_METADATA,
Andreas Huberfbb38852010-02-12 12:35:58 -080046 SUSPEND,
47 RESUME,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048};
49
50class BpMediaPlayer: public BpInterface<IMediaPlayer>
51{
52public:
53 BpMediaPlayer(const sp<IBinder>& impl)
54 : BpInterface<IMediaPlayer>(impl)
55 {
56 }
57
58 // disconnect from media player service
59 void disconnect()
60 {
61 Parcel data, reply;
62 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
63 remote()->transact(DISCONNECT, data, &reply);
64 }
65
66 status_t setVideoSurface(const sp<ISurface>& surface)
67 {
68 Parcel data, reply;
69 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
70 data.writeStrongBinder(surface->asBinder());
71 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
72 return reply.readInt32();
73 }
74
75 status_t prepareAsync()
76 {
77 Parcel data, reply;
78 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
79 remote()->transact(PREPARE_ASYNC, data, &reply);
80 return reply.readInt32();
81 }
82
83 status_t start()
84 {
85 Parcel data, reply;
86 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
87 remote()->transact(START, data, &reply);
88 return reply.readInt32();
89 }
90
91 status_t stop()
92 {
93 Parcel data, reply;
94 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
95 remote()->transact(STOP, data, &reply);
96 return reply.readInt32();
97 }
98
99 status_t isPlaying(bool* state)
100 {
101 Parcel data, reply;
102 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
103 remote()->transact(IS_PLAYING, data, &reply);
104 *state = reply.readInt32();
105 return reply.readInt32();
106 }
107
108 status_t pause()
109 {
110 Parcel data, reply;
111 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
112 remote()->transact(PAUSE, data, &reply);
113 return reply.readInt32();
114 }
115
116 status_t seekTo(int msec)
117 {
118 Parcel data, reply;
119 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
120 data.writeInt32(msec);
121 remote()->transact(SEEK_TO, data, &reply);
122 return reply.readInt32();
123 }
124
125 status_t getCurrentPosition(int* msec)
126 {
127 Parcel data, reply;
128 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
129 remote()->transact(GET_CURRENT_POSITION, data, &reply);
130 *msec = reply.readInt32();
131 return reply.readInt32();
132 }
133
134 status_t getDuration(int* msec)
135 {
136 Parcel data, reply;
137 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
138 remote()->transact(GET_DURATION, data, &reply);
139 *msec = reply.readInt32();
140 return reply.readInt32();
141 }
142
143 status_t reset()
144 {
145 Parcel data, reply;
146 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
147 remote()->transact(RESET, data, &reply);
148 return reply.readInt32();
149 }
150
151 status_t setAudioStreamType(int type)
152 {
153 Parcel data, reply;
154 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
155 data.writeInt32(type);
156 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
157 return reply.readInt32();
158 }
159
160 status_t setLooping(int loop)
161 {
162 Parcel data, reply;
163 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
164 data.writeInt32(loop);
165 remote()->transact(SET_LOOPING, data, &reply);
166 return reply.readInt32();
167 }
168
169 status_t setVolume(float leftVolume, float rightVolume)
170 {
171 Parcel data, reply;
Dave Sparks81494192009-05-26 14:39:29 -0700172 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 data.writeFloat(leftVolume);
174 data.writeFloat(rightVolume);
175 remote()->transact(SET_VOLUME, data, &reply);
176 return reply.readInt32();
177 }
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700178
179 status_t invoke(const Parcel& request, Parcel *reply)
180 { // Avoid doing any extra copy. The interface descriptor should
181 // have been set by MediaPlayer.java.
Nicolas Catania5d55c712009-07-09 09:21:33 -0700182 return remote()->transact(INVOKE, request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700183 }
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700184
185 status_t setMetadataFilter(const Parcel& request)
186 {
187 Parcel reply;
188 // Avoid doing any extra copy of the request. The interface
189 // descriptor should have been set by MediaPlayer.java.
190 remote()->transact(SET_METADATA_FILTER, request, &reply);
191 return reply.readInt32();
192 }
Nicolas Catania5d55c712009-07-09 09:21:33 -0700193
194 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
195 {
196 Parcel request;
197 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
198 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
199 request.writeInt32(update_only);
200 request.writeInt32(apply_filter);
201 remote()->transact(GET_METADATA, request, reply);
202 return reply->readInt32();
203 }
Andreas Huberfbb38852010-02-12 12:35:58 -0800204
205 status_t suspend() {
206 Parcel request;
207 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
208
209 Parcel reply;
210 remote()->transact(SUSPEND, request, &reply);
211
212 return reply.readInt32();
213 }
214
215 status_t resume() {
216 Parcel request;
217 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
218
219 Parcel reply;
220 remote()->transact(RESUME, request, &reply);
221
222 return reply.readInt32();
223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224};
225
nikodcd810d2009-06-22 08:49:52 -0700226IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
228// ----------------------------------------------------------------------
229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230status_t BnMediaPlayer::onTransact(
231 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
232{
233 switch(code) {
234 case DISCONNECT: {
235 CHECK_INTERFACE(IMediaPlayer, data, reply);
236 disconnect();
237 return NO_ERROR;
238 } break;
239 case SET_VIDEO_SURFACE: {
240 CHECK_INTERFACE(IMediaPlayer, data, reply);
241 sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
242 reply->writeInt32(setVideoSurface(surface));
243 return NO_ERROR;
244 } break;
245 case PREPARE_ASYNC: {
246 CHECK_INTERFACE(IMediaPlayer, data, reply);
247 reply->writeInt32(prepareAsync());
248 return NO_ERROR;
249 } break;
250 case START: {
251 CHECK_INTERFACE(IMediaPlayer, data, reply);
252 reply->writeInt32(start());
253 return NO_ERROR;
254 } break;
255 case STOP: {
256 CHECK_INTERFACE(IMediaPlayer, data, reply);
257 reply->writeInt32(stop());
258 return NO_ERROR;
259 } break;
260 case IS_PLAYING: {
261 CHECK_INTERFACE(IMediaPlayer, data, reply);
262 bool state;
263 status_t ret = isPlaying(&state);
264 reply->writeInt32(state);
265 reply->writeInt32(ret);
266 return NO_ERROR;
267 } break;
268 case PAUSE: {
269 CHECK_INTERFACE(IMediaPlayer, data, reply);
270 reply->writeInt32(pause());
271 return NO_ERROR;
272 } break;
273 case SEEK_TO: {
274 CHECK_INTERFACE(IMediaPlayer, data, reply);
275 reply->writeInt32(seekTo(data.readInt32()));
276 return NO_ERROR;
277 } break;
278 case GET_CURRENT_POSITION: {
279 CHECK_INTERFACE(IMediaPlayer, data, reply);
280 int msec;
281 status_t ret = getCurrentPosition(&msec);
282 reply->writeInt32(msec);
283 reply->writeInt32(ret);
284 return NO_ERROR;
285 } break;
286 case GET_DURATION: {
287 CHECK_INTERFACE(IMediaPlayer, data, reply);
288 int msec;
289 status_t ret = getDuration(&msec);
290 reply->writeInt32(msec);
291 reply->writeInt32(ret);
292 return NO_ERROR;
293 } break;
294 case RESET: {
295 CHECK_INTERFACE(IMediaPlayer, data, reply);
296 reply->writeInt32(reset());
297 return NO_ERROR;
298 } break;
299 case SET_AUDIO_STREAM_TYPE: {
300 CHECK_INTERFACE(IMediaPlayer, data, reply);
301 reply->writeInt32(setAudioStreamType(data.readInt32()));
302 return NO_ERROR;
303 } break;
304 case SET_LOOPING: {
305 CHECK_INTERFACE(IMediaPlayer, data, reply);
306 reply->writeInt32(setLooping(data.readInt32()));
307 return NO_ERROR;
308 } break;
309 case SET_VOLUME: {
Dave Sparks81494192009-05-26 14:39:29 -0700310 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
312 return NO_ERROR;
313 } break;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700314 case INVOKE: {
315 CHECK_INTERFACE(IMediaPlayer, data, reply);
316 invoke(data, reply);
317 return NO_ERROR;
318 } break;
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700319 case SET_METADATA_FILTER: {
320 CHECK_INTERFACE(IMediaPlayer, data, reply);
321 reply->writeInt32(setMetadataFilter(data));
322 return NO_ERROR;
323 } break;
Andreas Huberfbb38852010-02-12 12:35:58 -0800324 case SUSPEND: {
325 CHECK_INTERFACE(IMediaPlayer, data, reply);
326 reply->writeInt32(suspend());
327 return NO_ERROR;
328 } break;
329 case RESUME: {
330 CHECK_INTERFACE(IMediaPlayer, data, reply);
331 reply->writeInt32(resume());
332 return NO_ERROR;
333 } break;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700334 case GET_METADATA: {
335 CHECK_INTERFACE(IMediaPlayer, data, reply);
336 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
337 reply->setDataPosition(0);
338 reply->writeInt32(retcode);
339 reply->setDataPosition(0);
340 return NO_ERROR;
341 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 default:
343 return BBinder::onTransact(code, data, reply, flags);
344 }
345}
346
347// ----------------------------------------------------------------------------
348
349}; // namespace android