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
36 namespace android {
37
38 enum {
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
54 class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
55 {
56 public:
BpMediaPlayerService(const sp<IBinder> & impl)57 BpMediaPlayerService(const sp<IBinder>& impl)
58 : BpInterface<IMediaPlayerService>(impl)
59 {
60 }
61
createMetadataRetriever()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
create(const sp<IMediaPlayerClient> & client,int audioSessionId)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
createMediaRecorder()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
decode(const char * url,uint32_t * pSampleRate,int * pNumChannels,audio_format_t * pFormat,const sp<IMemoryHeap> & heap,size_t * pSize)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
decode(int fd,int64_t offset,int64_t length,uint32_t * pSampleRate,int * pNumChannels,audio_format_t * pFormat,const sp<IMemoryHeap> & heap,size_t * pSize)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
getOMX()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
makeCrypto()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
makeDrm()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
makeHDCP(bool createEncryptionModule)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
addBatteryData(uint32_t params)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
pullBatteryData(Parcel * reply)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
listenForRemoteDisplay(const sp<IRemoteDisplayClient> & client,const String8 & iface)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
updateProxyConfig(const char * host,int32_t port,const char * exclusionList)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
206 IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
207
208 // ----------------------------------------------------------------------
209
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)210 status_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