• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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