• 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/IMediaPlayerService.h>
24 #include <media/IMediaRecorder.h>
25 #include <media/IOMX.h>
26 
27 #include <utils/Errors.h>  // for status_t
28 
29 namespace android {
30 
31 enum {
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 
41 class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
42 {
43 public:
BpMediaPlayerService(const sp<IBinder> & impl)44     BpMediaPlayerService(const sp<IBinder>& impl)
45         : BpInterface<IMediaPlayerService>(impl)
46     {
47     }
48 
createMetadataRetriever(pid_t pid)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 
create(pid_t pid,const sp<IMediaPlayerClient> & client,const char * url,const KeyedVector<String8,String8> * headers,int audioSessionId)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 
createMediaRecorder(pid_t pid)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 
create(pid_t pid,const sp<IMediaPlayerClient> & client,int fd,int64_t offset,int64_t length,int audioSessionId)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 
decode(const char * url,uint32_t * pSampleRate,int * pNumChannels,int * pFormat)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 
decode(int fd,int64_t offset,int64_t length,uint32_t * pSampleRate,int * pNumChannels,int * pFormat)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 
getOMX()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 
144 IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
145 
146 // ----------------------------------------------------------------------
147 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)148 status_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