• 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 <ui/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 };
47 
48 class BpMediaPlayer: public BpInterface<IMediaPlayer>
49 {
50 public:
BpMediaPlayer(const sp<IBinder> & impl)51     BpMediaPlayer(const sp<IBinder>& impl)
52         : BpInterface<IMediaPlayer>(impl)
53     {
54     }
55 
56     // disconnect from media player service
disconnect()57     void disconnect()
58     {
59         Parcel data, reply;
60         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
61         remote()->transact(DISCONNECT, data, &reply);
62     }
63 
setVideoSurface(const sp<ISurface> & surface)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 
prepareAsync()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 
start()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 
stop()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 
isPlaying(bool * state)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 
pause()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 
seekTo(int msec)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 
getCurrentPosition(int * msec)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 
getDuration(int * msec)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 
reset()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 
setAudioStreamType(int type)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 
setLooping(int loop)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 
setVolume(float leftVolume,float rightVolume)167     status_t setVolume(float leftVolume, float rightVolume)
168     {
169         Parcel data, reply;
170         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
171         data.writeFloat(leftVolume);
172         data.writeFloat(rightVolume);
173         remote()->transact(SET_VOLUME, data, &reply);
174         return reply.readInt32();
175     }
176 
invoke(const Parcel & request,Parcel * reply)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.
180         return remote()->transact(INVOKE, request, reply);
181     }
182 
setMetadataFilter(const Parcel & request)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     }
191 
getMetadata(bool update_only,bool apply_filter,Parcel * reply)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     }
202 };
203 
204 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
205 
206 // ----------------------------------------------------------------------
207 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)208 status_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: {
288             CHECK_INTERFACE(IMediaPlayer, data, reply);
289             reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
290             return NO_ERROR;
291         } break;
292         case INVOKE: {
293             CHECK_INTERFACE(IMediaPlayer, data, reply);
294             invoke(data, reply);
295             return NO_ERROR;
296         } break;
297         case SET_METADATA_FILTER: {
298             CHECK_INTERFACE(IMediaPlayer, data, reply);
299             reply->writeInt32(setMetadataFilter(data));
300             return NO_ERROR;
301         } break;
302         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;
310         default:
311             return BBinder::onTransact(code, data, reply, flags);
312     }
313 }
314 
315 // ----------------------------------------------------------------------------
316 
317 }; // namespace android
318