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