IMediaPlayerService.cpp revision 3d00aa6de95fb46e36f2bab4e3facdf0b96acf06
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#include <binder/IMemory.h>
23#include <media/ICrypto.h>
24#include <media/IDrm.h>
25#include <media/IHDCP.h>
26#include <media/IMediaPlayerService.h>
27#include <media/IMediaRecorder.h>
28#include <media/IOMX.h>
29#include <media/IRemoteDisplay.h>
30#include <media/IRemoteDisplayClient.h>
31#include <media/IStreamSource.h>
32
33#include <utils/Errors.h>  // for status_t
34#include <utils/String8.h>
35
36namespace android {
37
38enum {
39    CREATE = IBinder::FIRST_CALL_TRANSACTION,
40    DECODE_URL,
41    DECODE_FD,
42    CREATE_MEDIA_RECORDER,
43    CREATE_METADATA_RETRIEVER,
44    GET_OMX,
45    MAKE_CRYPTO,
46    MAKE_DRM,
47    MAKE_HDCP,
48    ADD_BATTERY_DATA,
49    PULL_BATTERY_DATA,
50    LISTEN_FOR_REMOTE_DISPLAY,
51    UPDATE_PROXY_CONFIG,
52};
53
54class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
55{
56public:
57    BpMediaPlayerService(const sp<IBinder>& impl)
58        : BpInterface<IMediaPlayerService>(impl)
59    {
60    }
61
62    virtual sp<IMediaMetadataRetriever> createMetadataRetriever()
63    {
64        Parcel data, reply;
65        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
66        remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
67        return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
68    }
69
70    virtual sp<IMediaPlayer> create(
71            const sp<IMediaPlayerClient>& client, int audioSessionId) {
72        Parcel data, reply;
73        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
74        data.writeStrongBinder(client->asBinder());
75        data.writeInt32(audioSessionId);
76
77        remote()->transact(CREATE, data, &reply);
78        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
79    }
80
81    virtual sp<IMediaRecorder> createMediaRecorder()
82    {
83        Parcel data, reply;
84        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
85        remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
86        return interface_cast<IMediaRecorder>(reply.readStrongBinder());
87    }
88
89    virtual status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels,
90                               audio_format_t* pFormat,
91                               const sp<IMemoryHeap>& heap, size_t *pSize)
92    {
93        Parcel data, reply;
94        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
95        data.writeCString(url);
96        data.writeStrongBinder(heap->asBinder());
97        status_t status = remote()->transact(DECODE_URL, data, &reply);
98        if (status == NO_ERROR) {
99            status = (status_t)reply.readInt32();
100            if (status == NO_ERROR) {
101                *pSampleRate = uint32_t(reply.readInt32());
102                *pNumChannels = reply.readInt32();
103                *pFormat = (audio_format_t)reply.readInt32();
104                *pSize = (size_t)reply.readInt32();
105            }
106        }
107        return status;
108    }
109
110    virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate,
111                               int* pNumChannels, audio_format_t* pFormat,
112                               const sp<IMemoryHeap>& heap, size_t *pSize)
113    {
114        Parcel data, reply;
115        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
116        data.writeFileDescriptor(fd);
117        data.writeInt64(offset);
118        data.writeInt64(length);
119        data.writeStrongBinder(heap->asBinder());
120        status_t status = remote()->transact(DECODE_FD, data, &reply);
121        if (status == NO_ERROR) {
122            status = (status_t)reply.readInt32();
123            if (status == NO_ERROR) {
124                *pSampleRate = uint32_t(reply.readInt32());
125                *pNumChannels = reply.readInt32();
126                *pFormat = (audio_format_t)reply.readInt32();
127                *pSize = (size_t)reply.readInt32();
128            }
129        }
130        return status;
131    }
132
133    virtual sp<IOMX> getOMX() {
134        Parcel data, reply;
135        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
136        remote()->transact(GET_OMX, data, &reply);
137        return interface_cast<IOMX>(reply.readStrongBinder());
138    }
139
140    virtual sp<ICrypto> makeCrypto() {
141        Parcel data, reply;
142        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
143        remote()->transact(MAKE_CRYPTO, data, &reply);
144        return interface_cast<ICrypto>(reply.readStrongBinder());
145    }
146
147    virtual sp<IDrm> makeDrm() {
148        Parcel data, reply;
149        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
150        remote()->transact(MAKE_DRM, data, &reply);
151        return interface_cast<IDrm>(reply.readStrongBinder());
152    }
153
154    virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {
155        Parcel data, reply;
156        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
157        data.writeInt32(createEncryptionModule);
158        remote()->transact(MAKE_HDCP, data, &reply);
159        return interface_cast<IHDCP>(reply.readStrongBinder());
160    }
161
162    virtual void addBatteryData(uint32_t params) {
163        Parcel data, reply;
164        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
165        data.writeInt32(params);
166        remote()->transact(ADD_BATTERY_DATA, data, &reply);
167    }
168
169    virtual status_t pullBatteryData(Parcel* reply) {
170        Parcel data;
171        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
172        return remote()->transact(PULL_BATTERY_DATA, data, reply);
173    }
174
175    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client,
176            const String8& iface)
177    {
178        Parcel data, reply;
179        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
180        data.writeStrongBinder(client->asBinder());
181        data.writeString8(iface);
182        remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply);
183        return interface_cast<IRemoteDisplay>(reply.readStrongBinder());
184    }
185
186    virtual status_t updateProxyConfig(
187            const char *host, int32_t port, const char *exclusionList) {
188        Parcel data, reply;
189
190        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
191        if (host == NULL) {
192            data.writeInt32(0);
193        } else {
194            data.writeInt32(1);
195            data.writeCString(host);
196            data.writeInt32(port);
197            data.writeCString(exclusionList);
198        }
199
200        remote()->transact(UPDATE_PROXY_CONFIG, data, &reply);
201
202        return reply.readInt32();
203    }
204};
205
206IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
207
208// ----------------------------------------------------------------------
209
210status_t BnMediaPlayerService::onTransact(
211    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
212{
213    switch (code) {
214        case CREATE: {
215            CHECK_INTERFACE(IMediaPlayerService, data, reply);
216            sp<IMediaPlayerClient> client =
217                interface_cast<IMediaPlayerClient>(data.readStrongBinder());
218            int audioSessionId = data.readInt32();
219            sp<IMediaPlayer> player = create(client, audioSessionId);
220            reply->writeStrongBinder(player->asBinder());
221            return NO_ERROR;
222        } break;
223        case DECODE_URL: {
224            CHECK_INTERFACE(IMediaPlayerService, data, reply);
225            const char* url = data.readCString();
226            sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
227            uint32_t sampleRate;
228            int numChannels;
229            audio_format_t format;
230            size_t size;
231            status_t status = decode(url, &sampleRate, &numChannels, &format, heap, &size);
232            reply->writeInt32(status);
233            if (status == NO_ERROR) {
234                reply->writeInt32(sampleRate);
235                reply->writeInt32(numChannels);
236                reply->writeInt32((int32_t)format);
237                reply->writeInt32((int32_t)size);
238            }
239            return NO_ERROR;
240        } break;
241        case DECODE_FD: {
242            CHECK_INTERFACE(IMediaPlayerService, data, reply);
243            int fd = dup(data.readFileDescriptor());
244            int64_t offset = data.readInt64();
245            int64_t length = data.readInt64();
246            sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
247            uint32_t sampleRate;
248            int numChannels;
249            audio_format_t format;
250            size_t size;
251            status_t status = decode(fd, offset, length, &sampleRate, &numChannels, &format,
252                                     heap, &size);
253            reply->writeInt32(status);
254            if (status == NO_ERROR) {
255                reply->writeInt32(sampleRate);
256                reply->writeInt32(numChannels);
257                reply->writeInt32((int32_t)format);
258                reply->writeInt32((int32_t)size);
259            }
260            return NO_ERROR;
261        } break;
262        case CREATE_MEDIA_RECORDER: {
263            CHECK_INTERFACE(IMediaPlayerService, data, reply);
264            sp<IMediaRecorder> recorder = createMediaRecorder();
265            reply->writeStrongBinder(recorder->asBinder());
266            return NO_ERROR;
267        } break;
268        case CREATE_METADATA_RETRIEVER: {
269            CHECK_INTERFACE(IMediaPlayerService, data, reply);
270            sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
271            reply->writeStrongBinder(retriever->asBinder());
272            return NO_ERROR;
273        } break;
274        case GET_OMX: {
275            CHECK_INTERFACE(IMediaPlayerService, data, reply);
276            sp<IOMX> omx = getOMX();
277            reply->writeStrongBinder(omx->asBinder());
278            return NO_ERROR;
279        } break;
280        case MAKE_CRYPTO: {
281            CHECK_INTERFACE(IMediaPlayerService, data, reply);
282            sp<ICrypto> crypto = makeCrypto();
283            reply->writeStrongBinder(crypto->asBinder());
284            return NO_ERROR;
285        } break;
286        case MAKE_DRM: {
287            CHECK_INTERFACE(IMediaPlayerService, data, reply);
288            sp<IDrm> drm = makeDrm();
289            reply->writeStrongBinder(drm->asBinder());
290            return NO_ERROR;
291        } break;
292        case MAKE_HDCP: {
293            CHECK_INTERFACE(IMediaPlayerService, data, reply);
294            bool createEncryptionModule = data.readInt32();
295            sp<IHDCP> hdcp = makeHDCP(createEncryptionModule);
296            reply->writeStrongBinder(hdcp->asBinder());
297            return NO_ERROR;
298        } break;
299        case ADD_BATTERY_DATA: {
300            CHECK_INTERFACE(IMediaPlayerService, data, reply);
301            uint32_t params = data.readInt32();
302            addBatteryData(params);
303            return NO_ERROR;
304        } break;
305        case PULL_BATTERY_DATA: {
306            CHECK_INTERFACE(IMediaPlayerService, data, reply);
307            pullBatteryData(reply);
308            return NO_ERROR;
309        } break;
310        case LISTEN_FOR_REMOTE_DISPLAY: {
311            CHECK_INTERFACE(IMediaPlayerService, data, reply);
312            sp<IRemoteDisplayClient> client(
313                    interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
314            String8 iface(data.readString8());
315            sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface));
316            reply->writeStrongBinder(display->asBinder());
317            return NO_ERROR;
318        } break;
319        case UPDATE_PROXY_CONFIG:
320        {
321            CHECK_INTERFACE(IMediaPlayerService, data, reply);
322
323            const char *host = NULL;
324            int32_t port = 0;
325            const char *exclusionList = NULL;
326
327            if (data.readInt32()) {
328                host = data.readCString();
329                port = data.readInt32();
330                exclusionList = data.readCString();
331            }
332
333            reply->writeInt32(updateProxyConfig(host, port, exclusionList));
334
335            return OK;
336        }
337        default:
338            return BBinder::onTransact(code, data, reply, flags);
339    }
340}
341
342// ----------------------------------------------------------------------------
343
344}; // namespace android
345