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