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