blob: 5d9db102f6a21fd5b4813f6bcaf2acf0c9895f44 [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>
24#include <ui/ISurface.h>
25
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,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046};
47
48class BpMediaPlayer: public BpInterface<IMediaPlayer>
49{
50public:
51 BpMediaPlayer(const sp<IBinder>& impl)
52 : BpInterface<IMediaPlayer>(impl)
53 {
54 }
55
56 // disconnect from media player service
57 void disconnect()
58 {
59 Parcel data, reply;
60 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
61 remote()->transact(DISCONNECT, data, &reply);
62 }
63
64 status_t setVideoSurface(const sp<ISurface>& surface)
65 {
66 Parcel data, reply;
67 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
68 data.writeStrongBinder(surface->asBinder());
69 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
70 return reply.readInt32();
71 }
72
73 status_t prepareAsync()
74 {
75 Parcel data, reply;
76 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
77 remote()->transact(PREPARE_ASYNC, data, &reply);
78 return reply.readInt32();
79 }
80
81 status_t start()
82 {
83 Parcel data, reply;
84 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
85 remote()->transact(START, data, &reply);
86 return reply.readInt32();
87 }
88
89 status_t stop()
90 {
91 Parcel data, reply;
92 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
93 remote()->transact(STOP, data, &reply);
94 return reply.readInt32();
95 }
96
97 status_t isPlaying(bool* state)
98 {
99 Parcel data, reply;
100 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
101 remote()->transact(IS_PLAYING, data, &reply);
102 *state = reply.readInt32();
103 return reply.readInt32();
104 }
105
106 status_t pause()
107 {
108 Parcel data, reply;
109 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
110 remote()->transact(PAUSE, data, &reply);
111 return reply.readInt32();
112 }
113
114 status_t seekTo(int msec)
115 {
116 Parcel data, reply;
117 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
118 data.writeInt32(msec);
119 remote()->transact(SEEK_TO, data, &reply);
120 return reply.readInt32();
121 }
122
123 status_t getCurrentPosition(int* msec)
124 {
125 Parcel data, reply;
126 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
127 remote()->transact(GET_CURRENT_POSITION, data, &reply);
128 *msec = reply.readInt32();
129 return reply.readInt32();
130 }
131
132 status_t getDuration(int* msec)
133 {
134 Parcel data, reply;
135 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
136 remote()->transact(GET_DURATION, data, &reply);
137 *msec = reply.readInt32();
138 return reply.readInt32();
139 }
140
141 status_t reset()
142 {
143 Parcel data, reply;
144 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
145 remote()->transact(RESET, data, &reply);
146 return reply.readInt32();
147 }
148
149 status_t setAudioStreamType(int type)
150 {
151 Parcel data, reply;
152 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
153 data.writeInt32(type);
154 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
155 return reply.readInt32();
156 }
157
158 status_t setLooping(int loop)
159 {
160 Parcel data, reply;
161 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
162 data.writeInt32(loop);
163 remote()->transact(SET_LOOPING, data, &reply);
164 return reply.readInt32();
165 }
166
167 status_t setVolume(float leftVolume, float rightVolume)
168 {
169 Parcel data, reply;
Dave Sparks81494192009-05-26 14:39:29 -0700170 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 data.writeFloat(leftVolume);
172 data.writeFloat(rightVolume);
173 remote()->transact(SET_VOLUME, data, &reply);
174 return reply.readInt32();
175 }
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700176
177 status_t invoke(const Parcel& request, Parcel *reply)
178 { // Avoid doing any extra copy. The interface descriptor should
179 // have been set by MediaPlayer.java.
Nicolas Catania5d55c712009-07-09 09:21:33 -0700180 return remote()->transact(INVOKE, request, reply);
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700181 }
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700182
183 status_t setMetadataFilter(const Parcel& request)
184 {
185 Parcel reply;
186 // Avoid doing any extra copy of the request. The interface
187 // descriptor should have been set by MediaPlayer.java.
188 remote()->transact(SET_METADATA_FILTER, request, &reply);
189 return reply.readInt32();
190 }
Nicolas Catania5d55c712009-07-09 09:21:33 -0700191
192 status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
193 {
194 Parcel request;
195 request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
196 // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
197 request.writeInt32(update_only);
198 request.writeInt32(apply_filter);
199 remote()->transact(GET_METADATA, request, reply);
200 return reply->readInt32();
201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202};
203
nikodcd810d2009-06-22 08:49:52 -0700204IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205
206// ----------------------------------------------------------------------
207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208status_t BnMediaPlayer::onTransact(
209 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
210{
211 switch(code) {
212 case DISCONNECT: {
213 CHECK_INTERFACE(IMediaPlayer, data, reply);
214 disconnect();
215 return NO_ERROR;
216 } break;
217 case SET_VIDEO_SURFACE: {
218 CHECK_INTERFACE(IMediaPlayer, data, reply);
219 sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
220 reply->writeInt32(setVideoSurface(surface));
221 return NO_ERROR;
222 } break;
223 case PREPARE_ASYNC: {
224 CHECK_INTERFACE(IMediaPlayer, data, reply);
225 reply->writeInt32(prepareAsync());
226 return NO_ERROR;
227 } break;
228 case START: {
229 CHECK_INTERFACE(IMediaPlayer, data, reply);
230 reply->writeInt32(start());
231 return NO_ERROR;
232 } break;
233 case STOP: {
234 CHECK_INTERFACE(IMediaPlayer, data, reply);
235 reply->writeInt32(stop());
236 return NO_ERROR;
237 } break;
238 case IS_PLAYING: {
239 CHECK_INTERFACE(IMediaPlayer, data, reply);
240 bool state;
241 status_t ret = isPlaying(&state);
242 reply->writeInt32(state);
243 reply->writeInt32(ret);
244 return NO_ERROR;
245 } break;
246 case PAUSE: {
247 CHECK_INTERFACE(IMediaPlayer, data, reply);
248 reply->writeInt32(pause());
249 return NO_ERROR;
250 } break;
251 case SEEK_TO: {
252 CHECK_INTERFACE(IMediaPlayer, data, reply);
253 reply->writeInt32(seekTo(data.readInt32()));
254 return NO_ERROR;
255 } break;
256 case GET_CURRENT_POSITION: {
257 CHECK_INTERFACE(IMediaPlayer, data, reply);
258 int msec;
259 status_t ret = getCurrentPosition(&msec);
260 reply->writeInt32(msec);
261 reply->writeInt32(ret);
262 return NO_ERROR;
263 } break;
264 case GET_DURATION: {
265 CHECK_INTERFACE(IMediaPlayer, data, reply);
266 int msec;
267 status_t ret = getDuration(&msec);
268 reply->writeInt32(msec);
269 reply->writeInt32(ret);
270 return NO_ERROR;
271 } break;
272 case RESET: {
273 CHECK_INTERFACE(IMediaPlayer, data, reply);
274 reply->writeInt32(reset());
275 return NO_ERROR;
276 } break;
277 case SET_AUDIO_STREAM_TYPE: {
278 CHECK_INTERFACE(IMediaPlayer, data, reply);
279 reply->writeInt32(setAudioStreamType(data.readInt32()));
280 return NO_ERROR;
281 } break;
282 case SET_LOOPING: {
283 CHECK_INTERFACE(IMediaPlayer, data, reply);
284 reply->writeInt32(setLooping(data.readInt32()));
285 return NO_ERROR;
286 } break;
287 case SET_VOLUME: {
Dave Sparks81494192009-05-26 14:39:29 -0700288 CHECK_INTERFACE(IMediaPlayer, data, reply);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
290 return NO_ERROR;
291 } break;
Nicolas Catania20cb94e2009-05-12 23:25:55 -0700292 case INVOKE: {
293 CHECK_INTERFACE(IMediaPlayer, data, reply);
294 invoke(data, reply);
295 return NO_ERROR;
296 } break;
Nicolas Cataniab2c69392009-07-08 08:57:42 -0700297 case SET_METADATA_FILTER: {
298 CHECK_INTERFACE(IMediaPlayer, data, reply);
299 reply->writeInt32(setMetadataFilter(data));
300 return NO_ERROR;
301 } break;
Nicolas Catania5d55c712009-07-09 09:21:33 -0700302 case GET_METADATA: {
303 CHECK_INTERFACE(IMediaPlayer, data, reply);
304 const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
305 reply->setDataPosition(0);
306 reply->writeInt32(retcode);
307 reply->setDataPosition(0);
308 return NO_ERROR;
309 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 default:
311 return BBinder::onTransact(code, data, reply, flags);
312 }
313}
314
315// ----------------------------------------------------------------------------
316
317}; // namespace android