IMediaPlayer.cpp revision 2729ea9262ca60d93047e984739887cfc89e82eb
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 <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 296