IMediaPlayerService.cpp revision da7581b7b61b84f15e8d671c86fd117c322b009e
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/IMediaPlayerService.h>
24#include <media/IMediaRecorder.h>
25#include <media/IOMX.h>
26
27#include <utils/Errors.h>  // for status_t
28
29namespace android {
30
31enum {
32    CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
33    CREATE_FD,
34    DECODE_URL,
35    DECODE_FD,
36    CREATE_MEDIA_RECORDER,
37    CREATE_METADATA_RETRIEVER,
38    GET_OMX
39};
40
41class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
42{
43public:
44    BpMediaPlayerService(const sp<IBinder>& impl)
45        : BpInterface<IMediaPlayerService>(impl)
46    {
47    }
48
49    virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid)
50    {
51        Parcel data, reply;
52        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
53        data.writeInt32(pid);
54        remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
55        return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
56    }
57
58    virtual sp<IMediaPlayer> create(
59            pid_t pid, const sp<IMediaPlayerClient>& client,
60            const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) {
61        Parcel data, reply;
62        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
63        data.writeInt32(pid);
64        data.writeStrongBinder(client->asBinder());
65        data.writeCString(url);
66
67        if (headers == NULL) {
68            data.writeInt32(0);
69        } else {
70            // serialize the headers
71            data.writeInt32(headers->size());
72            for (size_t i = 0; i < headers->size(); ++i) {
73                data.writeString8(headers->keyAt(i));
74                data.writeString8(headers->valueAt(i));
75            }
76        }
77        data.writeInt32(audioSessionId);
78
79        remote()->transact(CREATE_URL, data, &reply);
80
81        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
82    }
83
84    virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid)
85    {
86        Parcel data, reply;
87        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
88        data.writeInt32(pid);
89        remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
90        return interface_cast<IMediaRecorder>(reply.readStrongBinder());
91    }
92
93    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd,
94            int64_t offset, int64_t length, int audioSessionId)
95    {
96        Parcel data, reply;
97        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
98        data.writeInt32(pid);
99        data.writeStrongBinder(client->asBinder());
100        data.writeFileDescriptor(fd);
101        data.writeInt64(offset);
102        data.writeInt64(length);
103        data.writeInt32(audioSessionId);
104
105        remote()->transact(CREATE_FD, data, &reply);
106
107        return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
108    }
109
110    virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
111    {
112        Parcel data, reply;
113        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
114        data.writeCString(url);
115        remote()->transact(DECODE_URL, data, &reply);
116        *pSampleRate = uint32_t(reply.readInt32());
117        *pNumChannels = reply.readInt32();
118        *pFormat = reply.readInt32();
119        return interface_cast<IMemory>(reply.readStrongBinder());
120    }
121
122    virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
123    {
124        Parcel data, reply;
125        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
126        data.writeFileDescriptor(fd);
127        data.writeInt64(offset);
128        data.writeInt64(length);
129        remote()->transact(DECODE_FD, data, &reply);
130        *pSampleRate = uint32_t(reply.readInt32());
131        *pNumChannels = reply.readInt32();
132        *pFormat = reply.readInt32();
133        return interface_cast<IMemory>(reply.readStrongBinder());
134    }
135
136    virtual sp<IOMX> getOMX() {
137        Parcel data, reply;
138        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
139        remote()->transact(GET_OMX, data, &reply);
140        return interface_cast<IOMX>(reply.readStrongBinder());
141    }
142};
143
144IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
145
146// ----------------------------------------------------------------------
147
148status_t BnMediaPlayerService::onTransact(
149    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
150{
151    switch(code) {
152        case CREATE_URL: {
153            CHECK_INTERFACE(IMediaPlayerService, data, reply);
154            pid_t pid = data.readInt32();
155            sp<IMediaPlayerClient> client =
156                interface_cast<IMediaPlayerClient>(data.readStrongBinder());
157            const char* url = data.readCString();
158
159            KeyedVector<String8, String8> headers;
160            int32_t numHeaders = data.readInt32();
161            for (int i = 0; i < numHeaders; ++i) {
162                String8 key = data.readString8();
163                String8 value = data.readString8();
164                headers.add(key, value);
165            }
166            int audioSessionId = data.readInt32();
167
168            sp<IMediaPlayer> player = create(
169                    pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId);
170
171            reply->writeStrongBinder(player->asBinder());
172            return NO_ERROR;
173        } break;
174        case CREATE_FD: {
175            CHECK_INTERFACE(IMediaPlayerService, data, reply);
176            pid_t pid = data.readInt32();
177            sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
178            int fd = dup(data.readFileDescriptor());
179            int64_t offset = data.readInt64();
180            int64_t length = data.readInt64();
181            int audioSessionId = data.readInt32();
182
183            sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId);
184            reply->writeStrongBinder(player->asBinder());
185            return NO_ERROR;
186        } break;
187        case DECODE_URL: {
188            CHECK_INTERFACE(IMediaPlayerService, data, reply);
189            const char* url = data.readCString();
190            uint32_t sampleRate;
191            int numChannels;
192            int format;
193            sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format);
194            reply->writeInt32(sampleRate);
195            reply->writeInt32(numChannels);
196            reply->writeInt32(format);
197            reply->writeStrongBinder(player->asBinder());
198            return NO_ERROR;
199        } break;
200        case DECODE_FD: {
201            CHECK_INTERFACE(IMediaPlayerService, data, reply);
202            int fd = dup(data.readFileDescriptor());
203            int64_t offset = data.readInt64();
204            int64_t length = data.readInt64();
205            uint32_t sampleRate;
206            int numChannels;
207            int format;
208            sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format);
209            reply->writeInt32(sampleRate);
210            reply->writeInt32(numChannels);
211            reply->writeInt32(format);
212            reply->writeStrongBinder(player->asBinder());
213            return NO_ERROR;
214        } break;
215        case CREATE_MEDIA_RECORDER: {
216            CHECK_INTERFACE(IMediaPlayerService, data, reply);
217            pid_t pid = data.readInt32();
218            sp<IMediaRecorder> recorder = createMediaRecorder(pid);
219            reply->writeStrongBinder(recorder->asBinder());
220            return NO_ERROR;
221        } break;
222        case CREATE_METADATA_RETRIEVER: {
223            CHECK_INTERFACE(IMediaPlayerService, data, reply);
224            pid_t pid = data.readInt32();
225            sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid);
226            reply->writeStrongBinder(retriever->asBinder());
227            return NO_ERROR;
228        } break;
229        case GET_OMX: {
230            CHECK_INTERFACE(IMediaPlayerService, data, reply);
231            sp<IOMX> omx = getOMX();
232            reply->writeStrongBinder(omx->asBinder());
233            return NO_ERROR;
234        } break;
235        default:
236            return BBinder::onTransact(code, data, reply, flags);
237    }
238}
239
240// ----------------------------------------------------------------------------
241
242}; // namespace android
243