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