blob: 1ae222ea4638a5d88be309b4fe5abd5862ebb78c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
Andreas Hubere46b7be2009-07-14 16:56:47 -070021#include <binder/Parcel.h>
Mathias Agopian07952722009-05-19 19:08:10 -070022#include <binder/IMemory.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include <media/IMediaPlayerService.h>
24#include <media/IMediaRecorder.h>
Andreas Hubere46b7be2009-07-14 16:56:47 -070025#include <media/IOMX.h>
26
27#include <utils/Errors.h> // for status_t
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
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,
Andreas Huber784202e2009-10-15 13:46:54 -070038 GET_OMX,
Marco Nelissenc39d2e32009-09-20 10:42:13 -070039 SNOOP
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040};
41
42class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
43{
44public:
45 BpMediaPlayerService(const sp<IBinder>& impl)
46 : BpInterface<IMediaPlayerService>(impl)
47 {
48 }
49
50 virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid)
51 {
52 Parcel data, reply;
53 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
54 data.writeInt32(pid);
55 remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
56 return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
57 }
58
Andreas Huber25643002010-01-28 11:19:57 -080059 virtual sp<IMediaPlayer> create(
60 pid_t pid, const sp<IMediaPlayerClient>& client,
Eric Laurent619346f2010-06-21 09:27:30 -070061 const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 Parcel data, reply;
63 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
64 data.writeInt32(pid);
65 data.writeStrongBinder(client->asBinder());
66 data.writeCString(url);
Andreas Huber25643002010-01-28 11:19:57 -080067
68 if (headers == NULL) {
69 data.writeInt32(0);
70 } else {
71 // serialize the headers
72 data.writeInt32(headers->size());
73 for (size_t i = 0; i < headers->size(); ++i) {
74 data.writeString8(headers->keyAt(i));
75 data.writeString8(headers->valueAt(i));
76 }
77 }
Eric Laurent619346f2010-06-21 09:27:30 -070078 data.writeInt32(audioSessionId);
Andreas Huber25643002010-01-28 11:19:57 -080079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 remote()->transact(CREATE_URL, data, &reply);
Eric Laurent619346f2010-06-21 09:27:30 -070081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 return interface_cast<IMediaPlayer>(reply.readStrongBinder());
83 }
84
85 virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid)
86 {
87 Parcel data, reply;
88 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
89 data.writeInt32(pid);
90 remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
91 return interface_cast<IMediaRecorder>(reply.readStrongBinder());
92 }
93
Eric Laurent619346f2010-06-21 09:27:30 -070094 virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd,
95 int64_t offset, int64_t length, int audioSessionId)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 {
97 Parcel data, reply;
98 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
99 data.writeInt32(pid);
100 data.writeStrongBinder(client->asBinder());
101 data.writeFileDescriptor(fd);
102 data.writeInt64(offset);
103 data.writeInt64(length);
Eric Laurent619346f2010-06-21 09:27:30 -0700104 data.writeInt32(audioSessionId);
105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 remote()->transact(CREATE_FD, data, &reply);
Eric Laurent619346f2010-06-21 09:27:30 -0700107
108 return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 }
110
111 virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
112 {
113 Parcel data, reply;
114 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
115 data.writeCString(url);
116 remote()->transact(DECODE_URL, data, &reply);
117 *pSampleRate = uint32_t(reply.readInt32());
118 *pNumChannels = reply.readInt32();
119 *pFormat = reply.readInt32();
120 return interface_cast<IMemory>(reply.readStrongBinder());
121 }
122
123 virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
124 {
125 Parcel data, reply;
126 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
127 data.writeFileDescriptor(fd);
128 data.writeInt64(offset);
129 data.writeInt64(length);
130 remote()->transact(DECODE_FD, data, &reply);
131 *pSampleRate = uint32_t(reply.readInt32());
132 *pNumChannels = reply.readInt32();
133 *pFormat = reply.readInt32();
134 return interface_cast<IMemory>(reply.readStrongBinder());
135 }
Andreas Hubere46b7be2009-07-14 16:56:47 -0700136
Marco Nelissenc39d2e32009-09-20 10:42:13 -0700137 virtual sp<IMemory> snoop()
138 {
139 Parcel data, reply;
140 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
141 remote()->transact(SNOOP, data, &reply);
142 return interface_cast<IMemory>(reply.readStrongBinder());
143 }
144
Andreas Huber784202e2009-10-15 13:46:54 -0700145 virtual sp<IOMX> getOMX() {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700146 Parcel data, reply;
147 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
Andreas Huber784202e2009-10-15 13:46:54 -0700148 remote()->transact(GET_OMX, data, &reply);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700149 return interface_cast<IOMX>(reply.readStrongBinder());
150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151};
152
nikodcd810d2009-06-22 08:49:52 -0700153IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154
155// ----------------------------------------------------------------------
156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157status_t BnMediaPlayerService::onTransact(
158 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
159{
160 switch(code) {
161 case CREATE_URL: {
162 CHECK_INTERFACE(IMediaPlayerService, data, reply);
163 pid_t pid = data.readInt32();
Andreas Huber25643002010-01-28 11:19:57 -0800164 sp<IMediaPlayerClient> client =
165 interface_cast<IMediaPlayerClient>(data.readStrongBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 const char* url = data.readCString();
Andreas Huber25643002010-01-28 11:19:57 -0800167
168 KeyedVector<String8, String8> headers;
169 int32_t numHeaders = data.readInt32();
170 for (int i = 0; i < numHeaders; ++i) {
171 String8 key = data.readString8();
172 String8 value = data.readString8();
173 headers.add(key, value);
174 }
Eric Laurent619346f2010-06-21 09:27:30 -0700175 int audioSessionId = data.readInt32();
Andreas Huber25643002010-01-28 11:19:57 -0800176
177 sp<IMediaPlayer> player = create(
Eric Laurent619346f2010-06-21 09:27:30 -0700178 pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId);
Andreas Huber25643002010-01-28 11:19:57 -0800179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 reply->writeStrongBinder(player->asBinder());
181 return NO_ERROR;
182 } break;
183 case CREATE_FD: {
184 CHECK_INTERFACE(IMediaPlayerService, data, reply);
185 pid_t pid = data.readInt32();
186 sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
187 int fd = dup(data.readFileDescriptor());
188 int64_t offset = data.readInt64();
189 int64_t length = data.readInt64();
Eric Laurent619346f2010-06-21 09:27:30 -0700190 int audioSessionId = data.readInt32();
191
192 sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 reply->writeStrongBinder(player->asBinder());
194 return NO_ERROR;
195 } break;
196 case DECODE_URL: {
197 CHECK_INTERFACE(IMediaPlayerService, data, reply);
198 const char* url = data.readCString();
199 uint32_t sampleRate;
200 int numChannels;
201 int format;
202 sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format);
203 reply->writeInt32(sampleRate);
204 reply->writeInt32(numChannels);
205 reply->writeInt32(format);
206 reply->writeStrongBinder(player->asBinder());
207 return NO_ERROR;
208 } break;
209 case DECODE_FD: {
210 CHECK_INTERFACE(IMediaPlayerService, data, reply);
211 int fd = dup(data.readFileDescriptor());
212 int64_t offset = data.readInt64();
213 int64_t length = data.readInt64();
214 uint32_t sampleRate;
215 int numChannels;
216 int format;
217 sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format);
218 reply->writeInt32(sampleRate);
219 reply->writeInt32(numChannels);
220 reply->writeInt32(format);
221 reply->writeStrongBinder(player->asBinder());
222 return NO_ERROR;
223 } break;
Marco Nelissenc39d2e32009-09-20 10:42:13 -0700224 case SNOOP: {
225 CHECK_INTERFACE(IMediaPlayerService, data, reply);
226 sp<IMemory> snooped_audio = snoop();
227 reply->writeStrongBinder(snooped_audio->asBinder());
228 return NO_ERROR;
229 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 case CREATE_MEDIA_RECORDER: {
231 CHECK_INTERFACE(IMediaPlayerService, data, reply);
232 pid_t pid = data.readInt32();
233 sp<IMediaRecorder> recorder = createMediaRecorder(pid);
234 reply->writeStrongBinder(recorder->asBinder());
235 return NO_ERROR;
236 } break;
237 case CREATE_METADATA_RETRIEVER: {
238 CHECK_INTERFACE(IMediaPlayerService, data, reply);
239 pid_t pid = data.readInt32();
240 sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid);
241 reply->writeStrongBinder(retriever->asBinder());
242 return NO_ERROR;
243 } break;
Andreas Huber784202e2009-10-15 13:46:54 -0700244 case GET_OMX: {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700245 CHECK_INTERFACE(IMediaPlayerService, data, reply);
Andreas Huber784202e2009-10-15 13:46:54 -0700246 sp<IOMX> omx = getOMX();
Andreas Hubere46b7be2009-07-14 16:56:47 -0700247 reply->writeStrongBinder(omx->asBinder());
248 return NO_ERROR;
249 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 default:
251 return BBinder::onTransact(code, data, reply, flags);
252 }
253}
254
255// ----------------------------------------------------------------------------
256
257}; // namespace android