/* ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include #include #include #include #include namespace android { enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_VIDEO_SURFACE, PREPARE_ASYNC, START, STOP, IS_PLAYING, PAUSE, GET_VIDEO_SIZE, SEEK_TO, GET_CURRENT_POSITION, GET_DURATION, RESET, SET_AUDIO_STREAM_TYPE, SET_LOOPING, SET_VOLUME }; class BpMediaPlayer: public BpInterface { public: BpMediaPlayer(const sp& impl) : BpInterface(impl) { } // disconnect from media player service void disconnect() { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(DISCONNECT, data, &reply); } status_t setVideoSurface(const sp& surface) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); data.writeStrongBinder(surface->asBinder()); remote()->transact(SET_VIDEO_SURFACE, data, &reply); return reply.readInt32(); } status_t prepareAsync() { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(PREPARE_ASYNC, data, &reply); return reply.readInt32(); } status_t start() { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(START, data, &reply); return reply.readInt32(); } status_t stop() { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(STOP, data, &reply); return reply.readInt32(); } status_t isPlaying(bool* state) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(IS_PLAYING, data, &reply); *state = reply.readInt32(); return reply.readInt32(); } status_t pause() { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(PAUSE, data, &reply); return reply.readInt32(); } status_t getVideoSize(int* w, int* h) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(GET_VIDEO_SIZE, data, &reply); *w = reply.readInt32(); *h = reply.readInt32(); return reply.readInt32(); } status_t seekTo(int msec) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); data.writeInt32(msec); remote()->transact(SEEK_TO, data, &reply); return reply.readInt32(); } status_t getCurrentPosition(int* msec) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(GET_CURRENT_POSITION, data, &reply); *msec = reply.readInt32(); return reply.readInt32(); } status_t getDuration(int* msec) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(GET_DURATION, data, &reply); *msec = reply.readInt32(); return reply.readInt32(); } status_t reset() { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); remote()->transact(RESET, data, &reply); return reply.readInt32(); } status_t setAudioStreamType(int type) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); data.writeInt32(type); remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply); return reply.readInt32(); } status_t setLooping(int loop) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); data.writeInt32(loop); remote()->transact(SET_LOOPING, data, &reply); return reply.readInt32(); } status_t setVolume(float leftVolume, float rightVolume) { Parcel data, reply; data.writeFloat(leftVolume); data.writeFloat(rightVolume); remote()->transact(SET_VOLUME, data, &reply); return reply.readInt32(); } }; IMPLEMENT_META_INTERFACE(MediaPlayer, "android.hardware.IMediaPlayer"); // ---------------------------------------------------------------------- #define CHECK_INTERFACE(interface, data, reply) \ do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ LOGW("Call incorrectly routed to " #interface); \ return PERMISSION_DENIED; \ } } while (0) status_t BnMediaPlayer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case DISCONNECT: { CHECK_INTERFACE(IMediaPlayer, data, reply); disconnect(); return NO_ERROR; } break; case SET_VIDEO_SURFACE: { CHECK_INTERFACE(IMediaPlayer, data, reply); sp surface = interface_cast(data.readStrongBinder()); reply->writeInt32(setVideoSurface(surface)); return NO_ERROR; } break; case PREPARE_ASYNC: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(prepareAsync()); return NO_ERROR; } break; case START: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(start()); return NO_ERROR; } break; case STOP: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(stop()); return NO_ERROR; } break; case IS_PLAYING: { CHECK_INTERFACE(IMediaPlayer, data, reply); bool state; status_t ret = isPlaying(&state); reply->writeInt32(state); reply->writeInt32(ret); return NO_ERROR; } break; case PAUSE: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(pause()); return NO_ERROR; } break; case GET_VIDEO_SIZE: { CHECK_INTERFACE(IMediaPlayer, data, reply); int w, h; status_t ret = getVideoSize(&w, &h); reply->writeInt32(w); reply->writeInt32(h); reply->writeInt32(ret); return NO_ERROR; } break; case SEEK_TO: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(seekTo(data.readInt32())); return NO_ERROR; } break; case GET_CURRENT_POSITION: { CHECK_INTERFACE(IMediaPlayer, data, reply); int msec; status_t ret = getCurrentPosition(&msec); reply->writeInt32(msec); reply->writeInt32(ret); return NO_ERROR; } break; case GET_DURATION: { CHECK_INTERFACE(IMediaPlayer, data, reply); int msec; status_t ret = getDuration(&msec); reply->writeInt32(msec); reply->writeInt32(ret); return NO_ERROR; } break; case RESET: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(reset()); return NO_ERROR; } break; case SET_AUDIO_STREAM_TYPE: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setAudioStreamType(data.readInt32())); return NO_ERROR; } break; case SET_LOOPING: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setLooping(data.readInt32())); return NO_ERROR; } break; case SET_VOLUME: { reply->writeInt32(setVolume(data.readFloat(), data.readFloat())); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android