blob: 838511429e70a00c708913ca475692cd44b0d7aa [file] [log] [blame]
The Android Open Source Project2729ea92008-10-21 07:00:00 -07001/*
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 <utils/Parcel.h>
22
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 GET_VIDEO_SIZE,
37 SEEK_TO,
38 GET_CURRENT_POSITION,
39 GET_DURATION,
40 RESET,
41 SET_AUDIO_STREAM_TYPE,
42 SET_LOOPING,
43 SET_VOLUME
44};
45
46class BpMediaPlayer: public BpInterface<IMediaPlayer>
47{
48public:
49 BpMediaPlayer(const sp<IBinder>& impl)
50 : BpInterface<IMediaPlayer>(impl)
51 {
52 }
53
54 // disconnect from media player service
55 void disconnect()
56 {
57 Parcel data, reply;
58 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
59 remote()->transact(DISCONNECT, data, &reply);
60 }
61
62 status_t setVideoSurface(const sp<ISurface>& surface)
63 {
64 Parcel data, reply;
65 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
66 data.writeStrongBinder(surface->asBinder());
67 remote()->transact(SET_VIDEO_SURFACE, data, &reply);
68 return reply.readInt32();
69 }
70
71 status_t prepareAsync()
72 {
73 Parcel data, reply;
74 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
75 remote()->transact(PREPARE_ASYNC, data, &reply);
76 return reply.readInt32();
77 }
78
79 status_t start()
80 {
81 Parcel data, reply;
82 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
83 remote()->transact(START, data, &reply);
84 return reply.readInt32();
85 }
86
87 status_t stop()
88 {
89 Parcel data, reply;
90 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
91 remote()->transact(STOP, data, &reply);
92 return reply.readInt32();
93 }
94
95 status_t isPlaying(bool* state)
96 {
97 Parcel data, reply;
98 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
99 remote()->transact(IS_PLAYING, data, &reply);
100 *state = reply.readInt32();
101 return reply.readInt32();
102 }
103
104 status_t pause()
105 {
106 Parcel data, reply;
107 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
108 remote()->transact(PAUSE, data, &reply);
109 return reply.readInt32();
110 }
111
112 status_t getVideoSize(int* w, int* h)
113 {
114 Parcel data, reply;
115 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
116 remote()->transact(GET_VIDEO_SIZE, data, &reply);
117 *w = reply.readInt32();
118 *h = reply.readInt32();
119 return reply.readInt32();
120 }
121
122 status_t seekTo(int msec)
123 {
124 Parcel data, reply;
125 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
126 data.writeInt32(msec);
127 remote()->transact(SEEK_TO, data, &reply);
128 return reply.readInt32();
129 }
130
131 status_t getCurrentPosition(int* msec)
132 {
133 Parcel data, reply;
134 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
135 remote()->transact(GET_CURRENT_POSITION, data, &reply);
136 *msec = reply.readInt32();
137 return reply.readInt32();
138 }
139
140 status_t getDuration(int* msec)
141 {
142 Parcel data, reply;
143 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
144 remote()->transact(GET_DURATION, data, &reply);
145 *msec = reply.readInt32();
146 return reply.readInt32();
147 }
148
149 status_t reset()
150 {
151 Parcel data, reply;
152 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
153 remote()->transact(RESET, data, &reply);
154 return reply.readInt32();
155 }
156
157 status_t setAudioStreamType(int type)
158 {
159 Parcel data, reply;
160 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
161 data.writeInt32(type);
162 remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
163 return reply.readInt32();
164 }
165
166 status_t setLooping(int loop)
167 {
168 Parcel data, reply;
169 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
170 data.writeInt32(loop);
171 remote()->transact(SET_LOOPING, data, &reply);
172 return reply.readInt32();
173 }
174
175 status_t setVolume(float leftVolume, float rightVolume)
176 {
177 Parcel data, reply;
178 data.writeFloat(leftVolume);
179 data.writeFloat(rightVolume);
180 remote()->transact(SET_VOLUME, data, &reply);
181 return reply.readInt32();
182 }
183};
184
185IMPLEMENT_META_INTERFACE(MediaPlayer, "android.hardware.IMediaPlayer");
186
187// ----------------------------------------------------------------------
188
189#define CHECK_INTERFACE(interface, data, reply) \
190 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
191 LOGW("Call incorrectly routed to " #interface); \
192 return PERMISSION_DENIED; \
193 } } while (0)
194
195status_t BnMediaPlayer::onTransact(
196 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
197{
198 switch(code) {
199 case DISCONNECT: {
200 CHECK_INTERFACE(IMediaPlayer, data, reply);
201 disconnect();
202 return NO_ERROR;
203 } break;
204 case SET_VIDEO_SURFACE: {
205 CHECK_INTERFACE(IMediaPlayer, data, reply);
206 sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
207 reply->writeInt32(setVideoSurface(surface));
208 return NO_ERROR;
209 } break;
210 case PREPARE_ASYNC: {
211 CHECK_INTERFACE(IMediaPlayer, data, reply);
212 reply->writeInt32(prepareAsync());
213 return NO_ERROR;
214 } break;
215 case START: {
216 CHECK_INTERFACE(IMediaPlayer, data, reply);
217 reply->writeInt32(start());
218 return NO_ERROR;
219 } break;
220 case STOP: {
221 CHECK_INTERFACE(IMediaPlayer, data, reply);
222 reply->writeInt32(stop());
223 return NO_ERROR;
224 } break;
225 case IS_PLAYING: {
226 CHECK_INTERFACE(IMediaPlayer, data, reply);
227 bool state;
228 status_t ret = isPlaying(&state);
229 reply->writeInt32(state);
230 reply->writeInt32(ret);
231 return NO_ERROR;
232 } break;
233 case PAUSE: {
234 CHECK_INTERFACE(IMediaPlayer, data, reply);
235 reply->writeInt32(pause());
236 return NO_ERROR;
237 } break;
238 case GET_VIDEO_SIZE: {
239 CHECK_INTERFACE(IMediaPlayer, data, reply);
240 int w, h;
241 status_t ret = getVideoSize(&w, &h);
242 reply->writeInt32(w);
243 reply->writeInt32(h);
244 reply->writeInt32(ret);
245 return NO_ERROR;
246 } break;
247 case SEEK_TO: {
248 CHECK_INTERFACE(IMediaPlayer, data, reply);
249 reply->writeInt32(seekTo(data.readInt32()));
250 return NO_ERROR;
251 } break;
252 case GET_CURRENT_POSITION: {
253 CHECK_INTERFACE(IMediaPlayer, data, reply);
254 int msec;
255 status_t ret = getCurrentPosition(&msec);
256 reply->writeInt32(msec);
257 reply->writeInt32(ret);
258 return NO_ERROR;
259 } break;
260 case GET_DURATION: {
261 CHECK_INTERFACE(IMediaPlayer, data, reply);
262 int msec;
263 status_t ret = getDuration(&msec);
264 reply->writeInt32(msec);
265 reply->writeInt32(ret);
266 return NO_ERROR;
267 } break;
268 case RESET: {
269 CHECK_INTERFACE(IMediaPlayer, data, reply);
270 reply->writeInt32(reset());
271 return NO_ERROR;
272 } break;
273 case SET_AUDIO_STREAM_TYPE: {
274 CHECK_INTERFACE(IMediaPlayer, data, reply);
275 reply->writeInt32(setAudioStreamType(data.readInt32()));
276 return NO_ERROR;
277 } break;
278 case SET_LOOPING: {
279 CHECK_INTERFACE(IMediaPlayer, data, reply);
280 reply->writeInt32(setLooping(data.readInt32()));
281 return NO_ERROR;
282 } break;
283 case SET_VOLUME: {
284 reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
285 return NO_ERROR;
286 } break;
287 default:
288 return BBinder::onTransact(code, data, reply, flags);
289 }
290}
291
292// ----------------------------------------------------------------------------
293
294}; // namespace android
295