IMediaPlayer.cpp revision 172fb9ab347e146642234f0bd6f223d351e9fd0b
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    SEEK_TO,
37    GET_CURRENT_POSITION,
38    GET_DURATION,
39    RESET,
40    SET_AUDIO_STREAM_TYPE,
41    SET_LOOPING,
42    SET_VOLUME
43};
44
45class BpMediaPlayer: public BpInterface<IMediaPlayer>
46{
47public:
48    BpMediaPlayer(const sp<IBinder>& impl)
49        : BpInterface<IMediaPlayer>(impl)
50    {
51    }
52
53    // disconnect from media player service
54    void disconnect()
55    {
56        Parcel data, reply;
57        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
58        remote()->transact(DISCONNECT, data, &reply);
59    }
60
61    status_t setVideoSurface(const sp<ISurface>& surface)
62    {
63        Parcel data, reply;
64        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
65        data.writeStrongBinder(surface->asBinder());
66        remote()->transact(SET_VIDEO_SURFACE, data, &reply);
67        return reply.readInt32();
68    }
69
70    status_t prepareAsync()
71    {
72        Parcel data, reply;
73        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
74        remote()->transact(PREPARE_ASYNC, data, &reply);
75        return reply.readInt32();
76    }
77
78    status_t start()
79    {
80        Parcel data, reply;
81        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
82        remote()->transact(START, data, &reply);
83        return reply.readInt32();
84    }
85
86    status_t stop()
87    {
88        Parcel data, reply;
89        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
90        remote()->transact(STOP, data, &reply);
91        return reply.readInt32();
92    }
93
94    status_t isPlaying(bool* state)
95    {
96        Parcel data, reply;
97        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
98        remote()->transact(IS_PLAYING, data, &reply);
99        *state = reply.readInt32();
100        return reply.readInt32();
101    }
102
103    status_t pause()
104    {
105        Parcel data, reply;
106        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
107        remote()->transact(PAUSE, data, &reply);
108        return reply.readInt32();
109    }
110
111    status_t seekTo(int msec)
112    {
113        Parcel data, reply;
114        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
115        data.writeInt32(msec);
116        remote()->transact(SEEK_TO, data, &reply);
117        return reply.readInt32();
118    }
119
120    status_t getCurrentPosition(int* msec)
121    {
122        Parcel data, reply;
123        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
124        remote()->transact(GET_CURRENT_POSITION, data, &reply);
125        *msec = reply.readInt32();
126        return reply.readInt32();
127    }
128
129    status_t getDuration(int* msec)
130    {
131        Parcel data, reply;
132        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
133        remote()->transact(GET_DURATION, data, &reply);
134        *msec = reply.readInt32();
135        return reply.readInt32();
136    }
137
138    status_t reset()
139    {
140        Parcel data, reply;
141        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
142        remote()->transact(RESET, data, &reply);
143        return reply.readInt32();
144    }
145
146    status_t setAudioStreamType(int type)
147    {
148        Parcel data, reply;
149        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
150        data.writeInt32(type);
151        remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
152        return reply.readInt32();
153    }
154
155    status_t setLooping(int loop)
156    {
157        Parcel data, reply;
158        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
159        data.writeInt32(loop);
160        remote()->transact(SET_LOOPING, data, &reply);
161        return reply.readInt32();
162    }
163
164    status_t setVolume(float leftVolume, float rightVolume)
165    {
166        Parcel data, reply;
167        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
168        data.writeFloat(leftVolume);
169        data.writeFloat(rightVolume);
170        remote()->transact(SET_VOLUME, data, &reply);
171        return reply.readInt32();
172    }
173};
174
175IMPLEMENT_META_INTERFACE(MediaPlayer, "android.hardware.IMediaPlayer");
176
177// ----------------------------------------------------------------------
178
179#define CHECK_INTERFACE(interface, data, reply) \
180        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
181            LOGW("Call incorrectly routed to " #interface); \
182            return PERMISSION_DENIED; \
183        } } while (0)
184
185status_t BnMediaPlayer::onTransact(
186    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
187{
188    switch(code) {
189        case DISCONNECT: {
190            CHECK_INTERFACE(IMediaPlayer, data, reply);
191            disconnect();
192            return NO_ERROR;
193        } break;
194        case SET_VIDEO_SURFACE: {
195            CHECK_INTERFACE(IMediaPlayer, data, reply);
196            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
197            reply->writeInt32(setVideoSurface(surface));
198            return NO_ERROR;
199        } break;
200        case PREPARE_ASYNC: {
201            CHECK_INTERFACE(IMediaPlayer, data, reply);
202            reply->writeInt32(prepareAsync());
203            return NO_ERROR;
204        } break;
205        case START: {
206            CHECK_INTERFACE(IMediaPlayer, data, reply);
207            reply->writeInt32(start());
208            return NO_ERROR;
209        } break;
210        case STOP: {
211            CHECK_INTERFACE(IMediaPlayer, data, reply);
212            reply->writeInt32(stop());
213            return NO_ERROR;
214        } break;
215        case IS_PLAYING: {
216            CHECK_INTERFACE(IMediaPlayer, data, reply);
217            bool state;
218            status_t ret = isPlaying(&state);
219            reply->writeInt32(state);
220            reply->writeInt32(ret);
221            return NO_ERROR;
222        } break;
223        case PAUSE: {
224            CHECK_INTERFACE(IMediaPlayer, data, reply);
225            reply->writeInt32(pause());
226            return NO_ERROR;
227        } break;
228        case SEEK_TO: {
229            CHECK_INTERFACE(IMediaPlayer, data, reply);
230            reply->writeInt32(seekTo(data.readInt32()));
231            return NO_ERROR;
232        } break;
233        case GET_CURRENT_POSITION: {
234            CHECK_INTERFACE(IMediaPlayer, data, reply);
235            int msec;
236            status_t ret = getCurrentPosition(&msec);
237            reply->writeInt32(msec);
238            reply->writeInt32(ret);
239            return NO_ERROR;
240        } break;
241        case GET_DURATION: {
242            CHECK_INTERFACE(IMediaPlayer, data, reply);
243            int msec;
244            status_t ret = getDuration(&msec);
245            reply->writeInt32(msec);
246            reply->writeInt32(ret);
247            return NO_ERROR;
248        } break;
249        case RESET: {
250            CHECK_INTERFACE(IMediaPlayer, data, reply);
251            reply->writeInt32(reset());
252            return NO_ERROR;
253        } break;
254        case SET_AUDIO_STREAM_TYPE: {
255            CHECK_INTERFACE(IMediaPlayer, data, reply);
256            reply->writeInt32(setAudioStreamType(data.readInt32()));
257            return NO_ERROR;
258        } break;
259        case SET_LOOPING: {
260            CHECK_INTERFACE(IMediaPlayer, data, reply);
261            reply->writeInt32(setLooping(data.readInt32()));
262            return NO_ERROR;
263        } break;
264        case SET_VOLUME: {
265            CHECK_INTERFACE(IMediaPlayer, data, reply);
266            reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
267            return NO_ERROR;
268        } break;
269        default:
270            return BBinder::onTransact(code, data, reply, flags);
271    }
272}
273
274// ----------------------------------------------------------------------------
275
276}; // namespace android
277
278