IMediaPlayer.cpp revision 3cf613507f1e2f7bd932d921a6e222e426fd3be4
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}; 47 48class BpMediaPlayer: public BpInterface<IMediaPlayer> 49{ 50public: 51 BpMediaPlayer(const sp<IBinder>& impl) 52 : BpInterface<IMediaPlayer>(impl) 53 { 54 } 55 56 // disconnect from media player service 57 void disconnect() 58 { 59 Parcel data, reply; 60 data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); 61 remote()->transact(DISCONNECT, data, &reply); 62 } 63 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 204IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); 205 206// ---------------------------------------------------------------------- 207 208status_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