IMediaHTTPConnection.cpp revision 1b86fe063badb5f28c467ade39be0f4008688947
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "IMediaHTTPConnection"
19#include <utils/Log.h>
20
21#include <media/IMediaHTTPConnection.h>
22
23#include <binder/IMemory.h>
24#include <binder/Parcel.h>
25#include <utils/String8.h>
26#include <media/stagefright/foundation/ADebug.h>
27
28namespace android {
29
30enum {
31    CONNECT = IBinder::FIRST_CALL_TRANSACTION,
32    DISCONNECT,
33    READ_AT,
34    GET_SIZE,
35    GET_MIME_TYPE,
36};
37
38struct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> {
39    BpMediaHTTPConnection(const sp<IBinder> &impl)
40        : BpInterface<IMediaHTTPConnection>(impl) {
41    }
42
43    virtual bool connect(
44            const char *uri, const KeyedVector<String8, String8> *headers) {
45        Parcel data, reply;
46        data.writeInterfaceToken(
47                IMediaHTTPConnection::getInterfaceDescriptor());
48
49        String16 tmp(uri);
50        data.writeString16(tmp);
51
52        tmp = String16("");
53        if (headers != NULL) {
54            for (size_t i = 0; i < headers->size(); ++i) {
55                String16 key(headers->keyAt(i).string());
56                String16 val(headers->valueAt(i).string());
57
58                tmp.append(key);
59                tmp.append(String16(": "));
60                tmp.append(val);
61                tmp.append(String16("\r\n"));
62            }
63        }
64        data.writeString16(tmp);
65
66        remote()->transact(CONNECT, data, &reply);
67
68        int32_t exceptionCode = reply.readExceptionCode();
69
70        if (exceptionCode) {
71            return UNKNOWN_ERROR;
72        }
73
74        sp<IBinder> binder = reply.readStrongBinder();
75        mMemory = interface_cast<IMemory>(binder);
76
77        return mMemory != NULL;
78    }
79
80    virtual void disconnect() {
81        Parcel data, reply;
82        data.writeInterfaceToken(
83                IMediaHTTPConnection::getInterfaceDescriptor());
84
85        remote()->transact(DISCONNECT, data, &reply);
86    }
87
88    virtual ssize_t readAt(off64_t offset, void *buffer, size_t size) {
89        Parcel data, reply;
90        data.writeInterfaceToken(
91                IMediaHTTPConnection::getInterfaceDescriptor());
92
93        data.writeInt64(offset);
94        data.writeInt32(size);
95
96        status_t err = remote()->transact(READ_AT, data, &reply);
97        CHECK_EQ(err, (status_t)OK);
98
99        int32_t exceptionCode = reply.readExceptionCode();
100
101        if (exceptionCode) {
102            return UNKNOWN_ERROR;
103        }
104
105        int32_t len = reply.readInt32();
106
107        if (len > 0) {
108            memcpy(buffer, mMemory->pointer(), len);
109        }
110
111        return len;
112    }
113
114    virtual off64_t getSize() {
115        Parcel data, reply;
116        data.writeInterfaceToken(
117                IMediaHTTPConnection::getInterfaceDescriptor());
118
119        remote()->transact(GET_SIZE, data, &reply);
120
121        int32_t exceptionCode = reply.readExceptionCode();
122
123        if (exceptionCode) {
124            return UNKNOWN_ERROR;
125        }
126
127        return reply.readInt64();
128    }
129
130    virtual status_t getMIMEType(String8 *mimeType) {
131        *mimeType = String8("");
132
133        Parcel data, reply;
134        data.writeInterfaceToken(
135                IMediaHTTPConnection::getInterfaceDescriptor());
136
137        remote()->transact(GET_MIME_TYPE, data, &reply);
138
139        int32_t exceptionCode = reply.readExceptionCode();
140
141        if (exceptionCode) {
142            return UNKNOWN_ERROR;
143        }
144
145        *mimeType = String8(reply.readString16());
146
147        return OK;
148    }
149
150private:
151    sp<IMemory> mMemory;
152};
153
154IMPLEMENT_META_INTERFACE(
155        MediaHTTPConnection, "android.media.IMediaHTTPConnection");
156
157}  // namespace android
158
159