11b86fe063badb5f28c467ade39be0f4008688947Andreas Huber/*
21b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * Copyright (C) 2013 The Android Open Source Project
31b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *
41b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * you may not use this file except in compliance with the License.
61b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * You may obtain a copy of the License at
71b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *
81b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91b86fe063badb5f28c467ade39be0f4008688947Andreas Huber *
101b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * Unless required by applicable law or agreed to in writing, software
111b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * See the License for the specific language governing permissions and
141b86fe063badb5f28c467ade39be0f4008688947Andreas Huber * limitations under the License.
151b86fe063badb5f28c467ade39be0f4008688947Andreas Huber */
161b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
171b86fe063badb5f28c467ade39be0f4008688947Andreas Huber//#define LOG_NDEBUG 0
181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#define LOG_TAG "IMediaHTTPConnection"
191b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <utils/Log.h>
201b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
211b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPConnection.h>
221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <binder/IMemory.h>
241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <binder/Parcel.h>
251b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <utils/String8.h>
261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2759cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen#include <media/stagefright/MediaErrors.h>
281b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
291b86fe063badb5f28c467ade39be0f4008688947Andreas Hubernamespace android {
301b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
311b86fe063badb5f28c467ade39be0f4008688947Andreas Huberenum {
321b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    CONNECT = IBinder::FIRST_CALL_TRANSACTION,
331b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    DISCONNECT,
341b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    READ_AT,
351b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    GET_SIZE,
361b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    GET_MIME_TYPE,
37c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen    GET_URI
381b86fe063badb5f28c467ade39be0f4008688947Andreas Huber};
391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
401b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstruct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> {
41090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BpMediaHTTPConnection(const sp<IBinder> &impl)
421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        : BpInterface<IMediaHTTPConnection>(impl) {
431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual bool connect(
461b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            const char *uri, const KeyedVector<String8, String8> *headers) {
471b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        String16 tmp(uri);
521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeString16(tmp);
531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
541b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        tmp = String16("");
551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (headers != NULL) {
561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            for (size_t i = 0; i < headers->size(); ++i) {
571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                String16 key(headers->keyAt(i).string());
581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                String16 val(headers->valueAt(i).string());
591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                tmp.append(key);
611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                tmp.append(String16(": "));
621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                tmp.append(val);
631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                tmp.append(String16("\r\n"));
641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            }
651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeString16(tmp);
671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
681b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        remote()->transact(CONNECT, data, &reply);
691b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
701b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        int32_t exceptionCode = reply.readExceptionCode();
711b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
721b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (exceptionCode) {
738cecf014ad5c62b072fad8fc24a140e8ee294f62Marco Nelissen            return false;
741b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
751b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
761b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        sp<IBinder> binder = reply.readStrongBinder();
771b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        mMemory = interface_cast<IMemory>(binder);
781b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
791b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return mMemory != NULL;
801b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
811b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
821b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual void disconnect() {
831b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
841b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
851b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
861b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
871b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        remote()->transact(DISCONNECT, data, &reply);
881b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
891b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
901b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual ssize_t readAt(off64_t offset, void *buffer, size_t size) {
911b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
921b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
931b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
941b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
951b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInt64(offset);
961b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInt32(size);
971b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        status_t err = remote()->transact(READ_AT, data, &reply);
9919a9fef6d2970a615f4f33025f9141e44b7c9f34Marco Nelissen        if (err != OK) {
10019a9fef6d2970a615f4f33025f9141e44b7c9f34Marco Nelissen            ALOGE("remote readAt failed");
10119a9fef6d2970a615f4f33025f9141e44b7c9f34Marco Nelissen            return UNKNOWN_ERROR;
10219a9fef6d2970a615f4f33025f9141e44b7c9f34Marco Nelissen        }
1031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1041b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        int32_t exceptionCode = reply.readExceptionCode();
1051b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1061b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (exceptionCode) {
1071b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            return UNKNOWN_ERROR;
1081b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
1091b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
11061c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin        int32_t lenOrErrorCode = reply.readInt32();
11161c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin
11261c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin        // Negative values are error codes
11361c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin        if (lenOrErrorCode < 0) {
11461c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin            return lenOrErrorCode;
11561c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin        }
11661c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin
11761c83317f1c8f18fd86afe0c776d16933816a83aAlex Klyubin        size_t len = lenOrErrorCode;
1181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
11959cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen        if (len > size) {
12059cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen            ALOGE("requested %zu, got %zu", size, len);
12159cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen            return ERROR_OUT_OF_RANGE;
1221b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
12359cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen        if (len > mMemory->size()) {
12459cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen            ALOGE("got %zu, but memory has %zu", len, mMemory->size());
12559cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen            return ERROR_OUT_OF_RANGE;
12659cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen        }
127a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara        if(buffer == NULL) {
128a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara           ALOGE("readAt got a NULL buffer");
129a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara           return UNKNOWN_ERROR;
130a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara        }
131a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara        if (mMemory->pointer() == NULL) {
132a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara           ALOGE("readAt got a NULL mMemory->pointer()");
133a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara           return UNKNOWN_ERROR;
134a04f6995de2e469cfb3164d88cf8fe54701c9124Santhosh Behara        }
13559cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen
13659cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen        memcpy(buffer, mMemory->pointer(), len);
1371b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1381b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return len;
1391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
1401b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual off64_t getSize() {
1421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
1431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
1441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
1451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1461b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        remote()->transact(GET_SIZE, data, &reply);
1471b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        int32_t exceptionCode = reply.readExceptionCode();
1491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (exceptionCode) {
1511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            return UNKNOWN_ERROR;
1521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
1531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1541b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return reply.readInt64();
1551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
1561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual status_t getMIMEType(String8 *mimeType) {
1581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        *mimeType = String8("");
1591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
1611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
1621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
1631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        remote()->transact(GET_MIME_TYPE, data, &reply);
1651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        int32_t exceptionCode = reply.readExceptionCode();
1671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1681b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (exceptionCode) {
1691b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            return UNKNOWN_ERROR;
1701b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
1711b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1721b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        *mimeType = String8(reply.readString16());
1731b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1741b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return OK;
1751b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
1761b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
177c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen    virtual status_t getUri(String8 *uri) {
178c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        *uri = String8("");
179c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
180c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        Parcel data, reply;
181c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        data.writeInterfaceToken(
182c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen                IMediaHTTPConnection::getInterfaceDescriptor());
183c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
184c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        remote()->transact(GET_URI, data, &reply);
185c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
186c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        int32_t exceptionCode = reply.readExceptionCode();
187c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
188c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        if (exceptionCode) {
189c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen            return UNKNOWN_ERROR;
190c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        }
191c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
192c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        *uri = String8(reply.readString16());
193c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
194c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        return OK;
195c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen    }
196c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
1971b86fe063badb5f28c467ade39be0f4008688947Andreas Huberprivate:
1981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    sp<IMemory> mMemory;
1991b86fe063badb5f28c467ade39be0f4008688947Andreas Huber};
2001b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
2011b86fe063badb5f28c467ade39be0f4008688947Andreas HuberIMPLEMENT_META_INTERFACE(
2021b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        MediaHTTPConnection, "android.media.IMediaHTTPConnection");
2031b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
204d2027336b45f524a196403d351ec317782793792Glenn Kasten} // namespace android
205