• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
21 #include <binder/Parcel.h>
22 
23 #include <media/IMediaPlayer.h>
24 #include <surfaceflinger/ISurface.h>
25 
26 namespace android {
27 
28 enum {
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,
42     SET_VOLUME,
43     INVOKE,
44     SET_METADATA_FILTER,
45     GET_METADATA,
46     SUSPEND,
47     RESUME,
48     SET_AUX_EFFECT_SEND_LEVEL,
49     ATTACH_AUX_EFFECT
50 };
51 
52 class BpMediaPlayer: public BpInterface<IMediaPlayer>
53 {
54 public:
BpMediaPlayer(const sp<IBinder> & impl)55     BpMediaPlayer(const sp<IBinder>& impl)
56         : BpInterface<IMediaPlayer>(impl)
57     {
58     }
59 
60     // disconnect from media player service
disconnect()61     void disconnect()
62     {
63         Parcel data, reply;
64         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
65         remote()->transact(DISCONNECT, data, &reply);
66     }
67 
setVideoSurface(const sp<ISurface> & surface)68     status_t setVideoSurface(const sp<ISurface>& surface)
69     {
70         Parcel data, reply;
71         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
72         data.writeStrongBinder(surface->asBinder());
73         remote()->transact(SET_VIDEO_SURFACE, data, &reply);
74         return reply.readInt32();
75     }
76 
prepareAsync()77     status_t prepareAsync()
78     {
79         Parcel data, reply;
80         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
81         remote()->transact(PREPARE_ASYNC, data, &reply);
82         return reply.readInt32();
83     }
84 
start()85     status_t start()
86     {
87         Parcel data, reply;
88         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
89         remote()->transact(START, data, &reply);
90         return reply.readInt32();
91     }
92 
stop()93     status_t stop()
94     {
95         Parcel data, reply;
96         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
97         remote()->transact(STOP, data, &reply);
98         return reply.readInt32();
99     }
100 
isPlaying(bool * state)101     status_t isPlaying(bool* state)
102     {
103         Parcel data, reply;
104         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
105         remote()->transact(IS_PLAYING, data, &reply);
106         *state = reply.readInt32();
107         return reply.readInt32();
108     }
109 
pause()110     status_t pause()
111     {
112         Parcel data, reply;
113         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
114         remote()->transact(PAUSE, data, &reply);
115         return reply.readInt32();
116     }
117 
seekTo(int msec)118     status_t seekTo(int msec)
119     {
120         Parcel data, reply;
121         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
122         data.writeInt32(msec);
123         remote()->transact(SEEK_TO, data, &reply);
124         return reply.readInt32();
125     }
126 
getCurrentPosition(int * msec)127     status_t getCurrentPosition(int* msec)
128     {
129         Parcel data, reply;
130         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
131         remote()->transact(GET_CURRENT_POSITION, data, &reply);
132         *msec = reply.readInt32();
133         return reply.readInt32();
134     }
135 
getDuration(int * msec)136     status_t getDuration(int* msec)
137     {
138         Parcel data, reply;
139         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
140         remote()->transact(GET_DURATION, data, &reply);
141         *msec = reply.readInt32();
142         return reply.readInt32();
143     }
144 
reset()145     status_t reset()
146     {
147         Parcel data, reply;
148         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
149         remote()->transact(RESET, data, &reply);
150         return reply.readInt32();
151     }
152 
setAudioStreamType(int type)153     status_t setAudioStreamType(int type)
154     {
155         Parcel data, reply;
156         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
157         data.writeInt32(type);
158         remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
159         return reply.readInt32();
160     }
161 
setLooping(int loop)162     status_t setLooping(int loop)
163     {
164         Parcel data, reply;
165         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
166         data.writeInt32(loop);
167         remote()->transact(SET_LOOPING, data, &reply);
168         return reply.readInt32();
169     }
170 
setVolume(float leftVolume,float rightVolume)171     status_t setVolume(float leftVolume, float rightVolume)
172     {
173         Parcel data, reply;
174         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
175         data.writeFloat(leftVolume);
176         data.writeFloat(rightVolume);
177         remote()->transact(SET_VOLUME, data, &reply);
178         return reply.readInt32();
179     }
180 
invoke(const Parcel & request,Parcel * reply)181     status_t invoke(const Parcel& request, Parcel *reply)
182     { // Avoid doing any extra copy. The interface descriptor should
183       // have been set by MediaPlayer.java.
184         return remote()->transact(INVOKE, request, reply);
185     }
186 
setMetadataFilter(const Parcel & request)187     status_t setMetadataFilter(const Parcel& request)
188     {
189         Parcel reply;
190         // Avoid doing any extra copy of the request. The interface
191         // descriptor should have been set by MediaPlayer.java.
192         remote()->transact(SET_METADATA_FILTER, request, &reply);
193         return reply.readInt32();
194     }
195 
getMetadata(bool update_only,bool apply_filter,Parcel * reply)196     status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply)
197     {
198         Parcel request;
199         request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
200         // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here.
201         request.writeInt32(update_only);
202         request.writeInt32(apply_filter);
203         remote()->transact(GET_METADATA, request, reply);
204         return reply->readInt32();
205     }
206 
suspend()207     status_t suspend() {
208         Parcel request;
209         request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
210 
211         Parcel reply;
212         remote()->transact(SUSPEND, request, &reply);
213 
214         return reply.readInt32();
215     }
216 
resume()217     status_t resume() {
218         Parcel request;
219         request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
220 
221         Parcel reply;
222         remote()->transact(RESUME, request, &reply);
223 
224         return reply.readInt32();
225     }
226 
setAuxEffectSendLevel(float level)227     status_t setAuxEffectSendLevel(float level)
228     {
229         Parcel data, reply;
230         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
231         data.writeFloat(level);
232         remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
233         return reply.readInt32();
234     }
235 
attachAuxEffect(int effectId)236     status_t attachAuxEffect(int effectId)
237     {
238         Parcel data, reply;
239         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
240         data.writeInt32(effectId);
241         remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
242         return reply.readInt32();
243     }
244 };
245 
246 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
247 
248 // ----------------------------------------------------------------------
249 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)250 status_t BnMediaPlayer::onTransact(
251     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
252 {
253     switch(code) {
254         case DISCONNECT: {
255             CHECK_INTERFACE(IMediaPlayer, data, reply);
256             disconnect();
257             return NO_ERROR;
258         } break;
259         case SET_VIDEO_SURFACE: {
260             CHECK_INTERFACE(IMediaPlayer, data, reply);
261             sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
262             reply->writeInt32(setVideoSurface(surface));
263             return NO_ERROR;
264         } break;
265         case PREPARE_ASYNC: {
266             CHECK_INTERFACE(IMediaPlayer, data, reply);
267             reply->writeInt32(prepareAsync());
268             return NO_ERROR;
269         } break;
270         case START: {
271             CHECK_INTERFACE(IMediaPlayer, data, reply);
272             reply->writeInt32(start());
273             return NO_ERROR;
274         } break;
275         case STOP: {
276             CHECK_INTERFACE(IMediaPlayer, data, reply);
277             reply->writeInt32(stop());
278             return NO_ERROR;
279         } break;
280         case IS_PLAYING: {
281             CHECK_INTERFACE(IMediaPlayer, data, reply);
282             bool state;
283             status_t ret = isPlaying(&state);
284             reply->writeInt32(state);
285             reply->writeInt32(ret);
286             return NO_ERROR;
287         } break;
288         case PAUSE: {
289             CHECK_INTERFACE(IMediaPlayer, data, reply);
290             reply->writeInt32(pause());
291             return NO_ERROR;
292         } break;
293         case SEEK_TO: {
294             CHECK_INTERFACE(IMediaPlayer, data, reply);
295             reply->writeInt32(seekTo(data.readInt32()));
296             return NO_ERROR;
297         } break;
298         case GET_CURRENT_POSITION: {
299             CHECK_INTERFACE(IMediaPlayer, data, reply);
300             int msec;
301             status_t ret = getCurrentPosition(&msec);
302             reply->writeInt32(msec);
303             reply->writeInt32(ret);
304             return NO_ERROR;
305         } break;
306         case GET_DURATION: {
307             CHECK_INTERFACE(IMediaPlayer, data, reply);
308             int msec;
309             status_t ret = getDuration(&msec);
310             reply->writeInt32(msec);
311             reply->writeInt32(ret);
312             return NO_ERROR;
313         } break;
314         case RESET: {
315             CHECK_INTERFACE(IMediaPlayer, data, reply);
316             reply->writeInt32(reset());
317             return NO_ERROR;
318         } break;
319         case SET_AUDIO_STREAM_TYPE: {
320             CHECK_INTERFACE(IMediaPlayer, data, reply);
321             reply->writeInt32(setAudioStreamType(data.readInt32()));
322             return NO_ERROR;
323         } break;
324         case SET_LOOPING: {
325             CHECK_INTERFACE(IMediaPlayer, data, reply);
326             reply->writeInt32(setLooping(data.readInt32()));
327             return NO_ERROR;
328         } break;
329         case SET_VOLUME: {
330             CHECK_INTERFACE(IMediaPlayer, data, reply);
331             reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
332             return NO_ERROR;
333         } break;
334         case INVOKE: {
335             CHECK_INTERFACE(IMediaPlayer, data, reply);
336             invoke(data, reply);
337             return NO_ERROR;
338         } break;
339         case SET_METADATA_FILTER: {
340             CHECK_INTERFACE(IMediaPlayer, data, reply);
341             reply->writeInt32(setMetadataFilter(data));
342             return NO_ERROR;
343         } break;
344         case SUSPEND: {
345             CHECK_INTERFACE(IMediaPlayer, data, reply);
346             reply->writeInt32(suspend());
347             return NO_ERROR;
348         } break;
349         case RESUME: {
350             CHECK_INTERFACE(IMediaPlayer, data, reply);
351             reply->writeInt32(resume());
352             return NO_ERROR;
353         } break;
354         case GET_METADATA: {
355             CHECK_INTERFACE(IMediaPlayer, data, reply);
356             const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
357             reply->setDataPosition(0);
358             reply->writeInt32(retcode);
359             reply->setDataPosition(0);
360             return NO_ERROR;
361         } break;
362         case SET_AUX_EFFECT_SEND_LEVEL: {
363             CHECK_INTERFACE(IMediaPlayer, data, reply);
364             reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
365             return NO_ERROR;
366         } break;
367         case ATTACH_AUX_EFFECT: {
368             CHECK_INTERFACE(IMediaPlayer, data, reply);
369             reply->writeInt32(attachAuxEffect(data.readInt32()));
370             return NO_ERROR;
371         } break;
372         default:
373             return BBinder::onTransact(code, data, reply, flags);
374     }
375 }
376 
377 // ----------------------------------------------------------------------------
378 
379 }; // namespace android
380