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