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> {
411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    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        }
12759cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen
12859cea2616269f34b1f3d046995efd8da42cd5549Marco Nelissen        memcpy(buffer, mMemory->pointer(), len);
1291b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1301b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return len;
1311b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
1321b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1331b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual off64_t getSize() {
1341b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
1351b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
1361b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
1371b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1381b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        remote()->transact(GET_SIZE, data, &reply);
1391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1401b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        int32_t exceptionCode = reply.readExceptionCode();
1411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1421b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (exceptionCode) {
1431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            return UNKNOWN_ERROR;
1441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
1451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1461b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return reply.readInt64();
1471b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
1481b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    virtual status_t getMIMEType(String8 *mimeType) {
1501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        *mimeType = String8("");
1511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        Parcel data, reply;
1531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        data.writeInterfaceToken(
1541b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                IMediaHTTPConnection::getInterfaceDescriptor());
1551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        remote()->transact(GET_MIME_TYPE, data, &reply);
1571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        int32_t exceptionCode = reply.readExceptionCode();
1591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        if (exceptionCode) {
1611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            return UNKNOWN_ERROR;
1621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        }
1631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        *mimeType = String8(reply.readString16());
1651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        return OK;
1671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    }
1681b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
169c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen    virtual status_t getUri(String8 *uri) {
170c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        *uri = String8("");
171c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
172c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        Parcel data, reply;
173c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        data.writeInterfaceToken(
174c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen                IMediaHTTPConnection::getInterfaceDescriptor());
175c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
176c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        remote()->transact(GET_URI, data, &reply);
177c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
178c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        int32_t exceptionCode = reply.readExceptionCode();
179c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
180c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        if (exceptionCode) {
181c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen            return UNKNOWN_ERROR;
182c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        }
183c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
184c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        *uri = String8(reply.readString16());
185c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
186c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen        return OK;
187c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen    }
188c9c7e25a4b1c34439fb365f6cfbef063884566ccMarco Nelissen
1891b86fe063badb5f28c467ade39be0f4008688947Andreas Huberprivate:
1901b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    sp<IMemory> mMemory;
1911b86fe063badb5f28c467ade39be0f4008688947Andreas Huber};
1921b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
1931b86fe063badb5f28c467ade39be0f4008688947Andreas HuberIMPLEMENT_META_INTERFACE(
1941b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        MediaHTTPConnection, "android.media.IMediaHTTPConnection");
1951b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
196d2027336b45f524a196403d351ec317782793792Glenn Kasten} // namespace android
197