1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0 18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "IMediaHTTPConnection" 19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h> 20*ec779b8eSAndroid Build Coastguard Worker 21*ec779b8eSAndroid Build Coastguard Worker #include <media/IMediaHTTPConnection.h> 22*ec779b8eSAndroid Build Coastguard Worker 23*ec779b8eSAndroid Build Coastguard Worker #include <binder/IMemory.h> 24*ec779b8eSAndroid Build Coastguard Worker #include <binder/Parcel.h> 25*ec779b8eSAndroid Build Coastguard Worker #include <utils/String8.h> 26*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h> 27*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaErrors.h> 28*ec779b8eSAndroid Build Coastguard Worker 29*ec779b8eSAndroid Build Coastguard Worker namespace android { 30*ec779b8eSAndroid Build Coastguard Worker 31*ec779b8eSAndroid Build Coastguard Worker enum { 32*ec779b8eSAndroid Build Coastguard Worker CONNECT = IBinder::FIRST_CALL_TRANSACTION, 33*ec779b8eSAndroid Build Coastguard Worker DISCONNECT, 34*ec779b8eSAndroid Build Coastguard Worker READ_AT, 35*ec779b8eSAndroid Build Coastguard Worker GET_SIZE, 36*ec779b8eSAndroid Build Coastguard Worker GET_MIME_TYPE, 37*ec779b8eSAndroid Build Coastguard Worker GET_URI 38*ec779b8eSAndroid Build Coastguard Worker }; 39*ec779b8eSAndroid Build Coastguard Worker 40*ec779b8eSAndroid Build Coastguard Worker struct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> { BpMediaHTTPConnectionandroid::BpMediaHTTPConnection41*ec779b8eSAndroid Build Coastguard Worker explicit BpMediaHTTPConnection(const sp<IBinder> &impl) 42*ec779b8eSAndroid Build Coastguard Worker : BpInterface<IMediaHTTPConnection>(impl) { 43*ec779b8eSAndroid Build Coastguard Worker } 44*ec779b8eSAndroid Build Coastguard Worker connectandroid::BpMediaHTTPConnection45*ec779b8eSAndroid Build Coastguard Worker virtual bool connect( 46*ec779b8eSAndroid Build Coastguard Worker const char *uri, const KeyedVector<String8, String8> *headers) { 47*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply; 48*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken( 49*ec779b8eSAndroid Build Coastguard Worker IMediaHTTPConnection::getInterfaceDescriptor()); 50*ec779b8eSAndroid Build Coastguard Worker 51*ec779b8eSAndroid Build Coastguard Worker String16 tmp(uri); 52*ec779b8eSAndroid Build Coastguard Worker data.writeString16(tmp); 53*ec779b8eSAndroid Build Coastguard Worker 54*ec779b8eSAndroid Build Coastguard Worker tmp = String16(""); 55*ec779b8eSAndroid Build Coastguard Worker if (headers != NULL) { 56*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < headers->size(); ++i) { 57*ec779b8eSAndroid Build Coastguard Worker String16 key(headers->keyAt(i).c_str()); 58*ec779b8eSAndroid Build Coastguard Worker String16 val(headers->valueAt(i).c_str()); 59*ec779b8eSAndroid Build Coastguard Worker 60*ec779b8eSAndroid Build Coastguard Worker tmp.append(key); 61*ec779b8eSAndroid Build Coastguard Worker tmp.append(String16(": ")); 62*ec779b8eSAndroid Build Coastguard Worker tmp.append(val); 63*ec779b8eSAndroid Build Coastguard Worker tmp.append(String16("\r\n")); 64*ec779b8eSAndroid Build Coastguard Worker } 65*ec779b8eSAndroid Build Coastguard Worker } 66*ec779b8eSAndroid Build Coastguard Worker data.writeString16(tmp); 67*ec779b8eSAndroid Build Coastguard Worker 68*ec779b8eSAndroid Build Coastguard Worker remote()->transact(CONNECT, data, &reply); 69*ec779b8eSAndroid Build Coastguard Worker 70*ec779b8eSAndroid Build Coastguard Worker int32_t exceptionCode = reply.readExceptionCode(); 71*ec779b8eSAndroid Build Coastguard Worker 72*ec779b8eSAndroid Build Coastguard Worker if (exceptionCode) { 73*ec779b8eSAndroid Build Coastguard Worker return false; 74*ec779b8eSAndroid Build Coastguard Worker } 75*ec779b8eSAndroid Build Coastguard Worker 76*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = reply.readStrongBinder(); 77*ec779b8eSAndroid Build Coastguard Worker mMemory = interface_cast<IMemory>(binder); 78*ec779b8eSAndroid Build Coastguard Worker 79*ec779b8eSAndroid Build Coastguard Worker return mMemory != NULL; 80*ec779b8eSAndroid Build Coastguard Worker } 81*ec779b8eSAndroid Build Coastguard Worker disconnectandroid::BpMediaHTTPConnection82*ec779b8eSAndroid Build Coastguard Worker virtual void disconnect() { 83*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply; 84*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken( 85*ec779b8eSAndroid Build Coastguard Worker IMediaHTTPConnection::getInterfaceDescriptor()); 86*ec779b8eSAndroid Build Coastguard Worker 87*ec779b8eSAndroid Build Coastguard Worker remote()->transact(DISCONNECT, data, &reply); 88*ec779b8eSAndroid Build Coastguard Worker } 89*ec779b8eSAndroid Build Coastguard Worker readAtandroid::BpMediaHTTPConnection90*ec779b8eSAndroid Build Coastguard Worker virtual ssize_t readAt(off64_t offset, void *buffer, size_t size) { 91*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply; 92*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken( 93*ec779b8eSAndroid Build Coastguard Worker IMediaHTTPConnection::getInterfaceDescriptor()); 94*ec779b8eSAndroid Build Coastguard Worker 95*ec779b8eSAndroid Build Coastguard Worker data.writeInt64(offset); 96*ec779b8eSAndroid Build Coastguard Worker data.writeInt32(size); 97*ec779b8eSAndroid Build Coastguard Worker 98*ec779b8eSAndroid Build Coastguard Worker status_t err = remote()->transact(READ_AT, data, &reply); 99*ec779b8eSAndroid Build Coastguard Worker if (err != OK) { 100*ec779b8eSAndroid Build Coastguard Worker ALOGE("remote readAt failed"); 101*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 102*ec779b8eSAndroid Build Coastguard Worker } 103*ec779b8eSAndroid Build Coastguard Worker 104*ec779b8eSAndroid Build Coastguard Worker int32_t exceptionCode = reply.readExceptionCode(); 105*ec779b8eSAndroid Build Coastguard Worker 106*ec779b8eSAndroid Build Coastguard Worker if (exceptionCode) { 107*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 108*ec779b8eSAndroid Build Coastguard Worker } 109*ec779b8eSAndroid Build Coastguard Worker 110*ec779b8eSAndroid Build Coastguard Worker int32_t lenOrErrorCode = reply.readInt32(); 111*ec779b8eSAndroid Build Coastguard Worker 112*ec779b8eSAndroid Build Coastguard Worker // Negative values are error codes 113*ec779b8eSAndroid Build Coastguard Worker if (lenOrErrorCode < 0) { 114*ec779b8eSAndroid Build Coastguard Worker return lenOrErrorCode; 115*ec779b8eSAndroid Build Coastguard Worker } 116*ec779b8eSAndroid Build Coastguard Worker 117*ec779b8eSAndroid Build Coastguard Worker size_t len = lenOrErrorCode; 118*ec779b8eSAndroid Build Coastguard Worker 119*ec779b8eSAndroid Build Coastguard Worker if (len > size) { 120*ec779b8eSAndroid Build Coastguard Worker ALOGE("requested %zu, got %zu", size, len); 121*ec779b8eSAndroid Build Coastguard Worker return ERROR_OUT_OF_RANGE; 122*ec779b8eSAndroid Build Coastguard Worker } 123*ec779b8eSAndroid Build Coastguard Worker if (len > mMemory->size()) { 124*ec779b8eSAndroid Build Coastguard Worker ALOGE("got %zu, but memory has %zu", len, mMemory->size()); 125*ec779b8eSAndroid Build Coastguard Worker return ERROR_OUT_OF_RANGE; 126*ec779b8eSAndroid Build Coastguard Worker } 127*ec779b8eSAndroid Build Coastguard Worker if(buffer == NULL) { 128*ec779b8eSAndroid Build Coastguard Worker ALOGE("readAt got a NULL buffer"); 129*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 130*ec779b8eSAndroid Build Coastguard Worker } 131*ec779b8eSAndroid Build Coastguard Worker if (mMemory->unsecurePointer() == NULL) { 132*ec779b8eSAndroid Build Coastguard Worker ALOGE("readAt got a NULL mMemory->unsecurePointer()"); 133*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 134*ec779b8eSAndroid Build Coastguard Worker } 135*ec779b8eSAndroid Build Coastguard Worker 136*ec779b8eSAndroid Build Coastguard Worker memcpy(buffer, mMemory->unsecurePointer(), len); 137*ec779b8eSAndroid Build Coastguard Worker 138*ec779b8eSAndroid Build Coastguard Worker return len; 139*ec779b8eSAndroid Build Coastguard Worker } 140*ec779b8eSAndroid Build Coastguard Worker getSizeandroid::BpMediaHTTPConnection141*ec779b8eSAndroid Build Coastguard Worker virtual off64_t getSize() { 142*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply; 143*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken( 144*ec779b8eSAndroid Build Coastguard Worker IMediaHTTPConnection::getInterfaceDescriptor()); 145*ec779b8eSAndroid Build Coastguard Worker 146*ec779b8eSAndroid Build Coastguard Worker remote()->transact(GET_SIZE, data, &reply); 147*ec779b8eSAndroid Build Coastguard Worker 148*ec779b8eSAndroid Build Coastguard Worker int32_t exceptionCode = reply.readExceptionCode(); 149*ec779b8eSAndroid Build Coastguard Worker 150*ec779b8eSAndroid Build Coastguard Worker if (exceptionCode) { 151*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 152*ec779b8eSAndroid Build Coastguard Worker } 153*ec779b8eSAndroid Build Coastguard Worker 154*ec779b8eSAndroid Build Coastguard Worker return reply.readInt64(); 155*ec779b8eSAndroid Build Coastguard Worker } 156*ec779b8eSAndroid Build Coastguard Worker getMIMETypeandroid::BpMediaHTTPConnection157*ec779b8eSAndroid Build Coastguard Worker virtual status_t getMIMEType(String8 *mimeType) { 158*ec779b8eSAndroid Build Coastguard Worker *mimeType = String8(""); 159*ec779b8eSAndroid Build Coastguard Worker 160*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply; 161*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken( 162*ec779b8eSAndroid Build Coastguard Worker IMediaHTTPConnection::getInterfaceDescriptor()); 163*ec779b8eSAndroid Build Coastguard Worker 164*ec779b8eSAndroid Build Coastguard Worker remote()->transact(GET_MIME_TYPE, data, &reply); 165*ec779b8eSAndroid Build Coastguard Worker 166*ec779b8eSAndroid Build Coastguard Worker int32_t exceptionCode = reply.readExceptionCode(); 167*ec779b8eSAndroid Build Coastguard Worker 168*ec779b8eSAndroid Build Coastguard Worker if (exceptionCode) { 169*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 170*ec779b8eSAndroid Build Coastguard Worker } 171*ec779b8eSAndroid Build Coastguard Worker 172*ec779b8eSAndroid Build Coastguard Worker *mimeType = String8(reply.readString16()); 173*ec779b8eSAndroid Build Coastguard Worker 174*ec779b8eSAndroid Build Coastguard Worker return OK; 175*ec779b8eSAndroid Build Coastguard Worker } 176*ec779b8eSAndroid Build Coastguard Worker getUriandroid::BpMediaHTTPConnection177*ec779b8eSAndroid Build Coastguard Worker virtual status_t getUri(String8 *uri) { 178*ec779b8eSAndroid Build Coastguard Worker *uri = String8(""); 179*ec779b8eSAndroid Build Coastguard Worker 180*ec779b8eSAndroid Build Coastguard Worker Parcel data, reply; 181*ec779b8eSAndroid Build Coastguard Worker data.writeInterfaceToken( 182*ec779b8eSAndroid Build Coastguard Worker IMediaHTTPConnection::getInterfaceDescriptor()); 183*ec779b8eSAndroid Build Coastguard Worker 184*ec779b8eSAndroid Build Coastguard Worker remote()->transact(GET_URI, data, &reply); 185*ec779b8eSAndroid Build Coastguard Worker 186*ec779b8eSAndroid Build Coastguard Worker int32_t exceptionCode = reply.readExceptionCode(); 187*ec779b8eSAndroid Build Coastguard Worker 188*ec779b8eSAndroid Build Coastguard Worker if (exceptionCode) { 189*ec779b8eSAndroid Build Coastguard Worker return UNKNOWN_ERROR; 190*ec779b8eSAndroid Build Coastguard Worker } 191*ec779b8eSAndroid Build Coastguard Worker 192*ec779b8eSAndroid Build Coastguard Worker *uri = String8(reply.readString16()); 193*ec779b8eSAndroid Build Coastguard Worker 194*ec779b8eSAndroid Build Coastguard Worker return OK; 195*ec779b8eSAndroid Build Coastguard Worker } 196*ec779b8eSAndroid Build Coastguard Worker 197*ec779b8eSAndroid Build Coastguard Worker private: 198*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> mMemory; 199*ec779b8eSAndroid Build Coastguard Worker }; 200*ec779b8eSAndroid Build Coastguard Worker 201*ec779b8eSAndroid Build Coastguard Worker IMPLEMENT_META_INTERFACE( 202*ec779b8eSAndroid Build Coastguard Worker MediaHTTPConnection, "android.media.IMediaHTTPConnection"); 203*ec779b8eSAndroid Build Coastguard Worker 204*ec779b8eSAndroid Build Coastguard Worker } // namespace android 205