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