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