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: 59 BpMediaPlayerService(const sp<IBinder>& impl) 60 : BpInterface<IMediaPlayerService>(impl) 61 { 62 } 63 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 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 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 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 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 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 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 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 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 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 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 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 197 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 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