blob: 1bb8d67c0f9a83627c2c6eddd412be78c9295d64 [file] [log] [blame]
Andreas Huber1b86fe02014-01-29 11:13:26 -08001/*
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>
Marco Nelissen59cea262015-04-20 11:08:59 -070027#include <media/stagefright/MediaErrors.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080028
29namespace android {
30
31enum {
32 CONNECT = IBinder::FIRST_CALL_TRANSACTION,
33 DISCONNECT,
34 READ_AT,
35 GET_SIZE,
36 GET_MIME_TYPE,
Marco Nelissenc9c7e252014-02-21 12:01:23 -080037 GET_URI
Andreas Huber1b86fe02014-01-29 11:13:26 -080038};
39
40struct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070041 explicit BpMediaHTTPConnection(const sp<IBinder> &impl)
Andreas Huber1b86fe02014-01-29 11:13:26 -080042 : BpInterface<IMediaHTTPConnection>(impl) {
43 }
44
45 virtual bool connect(
46 const char *uri, const KeyedVector<String8, String8> *headers) {
47 Parcel data, reply;
48 data.writeInterfaceToken(
49 IMediaHTTPConnection::getInterfaceDescriptor());
50
51 String16 tmp(uri);
52 data.writeString16(tmp);
53
54 tmp = String16("");
55 if (headers != NULL) {
56 for (size_t i = 0; i < headers->size(); ++i) {
57 String16 key(headers->keyAt(i).string());
58 String16 val(headers->valueAt(i).string());
59
60 tmp.append(key);
61 tmp.append(String16(": "));
62 tmp.append(val);
63 tmp.append(String16("\r\n"));
64 }
65 }
66 data.writeString16(tmp);
67
68 remote()->transact(CONNECT, data, &reply);
69
70 int32_t exceptionCode = reply.readExceptionCode();
71
72 if (exceptionCode) {
Marco Nelissen8cecf012015-06-11 14:08:44 -070073 return false;
Andreas Huber1b86fe02014-01-29 11:13:26 -080074 }
75
76 sp<IBinder> binder = reply.readStrongBinder();
77 mMemory = interface_cast<IMemory>(binder);
78
79 return mMemory != NULL;
80 }
81
82 virtual void disconnect() {
83 Parcel data, reply;
84 data.writeInterfaceToken(
85 IMediaHTTPConnection::getInterfaceDescriptor());
86
87 remote()->transact(DISCONNECT, data, &reply);
88 }
89
90 virtual ssize_t readAt(off64_t offset, void *buffer, size_t size) {
91 Parcel data, reply;
92 data.writeInterfaceToken(
93 IMediaHTTPConnection::getInterfaceDescriptor());
94
95 data.writeInt64(offset);
96 data.writeInt32(size);
97
98 status_t err = remote()->transact(READ_AT, data, &reply);
Marco Nelissen19a9fef2014-02-27 13:20:07 -080099 if (err != OK) {
100 ALOGE("remote readAt failed");
101 return UNKNOWN_ERROR;
102 }
Andreas Huber1b86fe02014-01-29 11:13:26 -0800103
104 int32_t exceptionCode = reply.readExceptionCode();
105
106 if (exceptionCode) {
107 return UNKNOWN_ERROR;
108 }
109
Alex Klyubin61c83312015-06-18 12:39:44 -0700110 int32_t lenOrErrorCode = reply.readInt32();
111
112 // Negative values are error codes
113 if (lenOrErrorCode < 0) {
114 return lenOrErrorCode;
115 }
116
117 size_t len = lenOrErrorCode;
Andreas Huber1b86fe02014-01-29 11:13:26 -0800118
Marco Nelissen59cea262015-04-20 11:08:59 -0700119 if (len > size) {
120 ALOGE("requested %zu, got %zu", size, len);
121 return ERROR_OUT_OF_RANGE;
Andreas Huber1b86fe02014-01-29 11:13:26 -0800122 }
Marco Nelissen59cea262015-04-20 11:08:59 -0700123 if (len > mMemory->size()) {
124 ALOGE("got %zu, but memory has %zu", len, mMemory->size());
125 return ERROR_OUT_OF_RANGE;
126 }
Santhosh Beharaa04f6992015-11-04 13:20:52 -0800127 if(buffer == NULL) {
128 ALOGE("readAt got a NULL buffer");
129 return UNKNOWN_ERROR;
130 }
131 if (mMemory->pointer() == NULL) {
132 ALOGE("readAt got a NULL mMemory->pointer()");
133 return UNKNOWN_ERROR;
134 }
Marco Nelissen59cea262015-04-20 11:08:59 -0700135
136 memcpy(buffer, mMemory->pointer(), len);
Andreas Huber1b86fe02014-01-29 11:13:26 -0800137
138 return len;
139 }
140
141 virtual off64_t getSize() {
142 Parcel data, reply;
143 data.writeInterfaceToken(
144 IMediaHTTPConnection::getInterfaceDescriptor());
145
146 remote()->transact(GET_SIZE, data, &reply);
147
148 int32_t exceptionCode = reply.readExceptionCode();
149
150 if (exceptionCode) {
151 return UNKNOWN_ERROR;
152 }
153
154 return reply.readInt64();
155 }
156
157 virtual status_t getMIMEType(String8 *mimeType) {
158 *mimeType = String8("");
159
160 Parcel data, reply;
161 data.writeInterfaceToken(
162 IMediaHTTPConnection::getInterfaceDescriptor());
163
164 remote()->transact(GET_MIME_TYPE, data, &reply);
165
166 int32_t exceptionCode = reply.readExceptionCode();
167
168 if (exceptionCode) {
169 return UNKNOWN_ERROR;
170 }
171
172 *mimeType = String8(reply.readString16());
173
174 return OK;
175 }
176
Marco Nelissenc9c7e252014-02-21 12:01:23 -0800177 virtual status_t getUri(String8 *uri) {
178 *uri = String8("");
179
180 Parcel data, reply;
181 data.writeInterfaceToken(
182 IMediaHTTPConnection::getInterfaceDescriptor());
183
184 remote()->transact(GET_URI, data, &reply);
185
186 int32_t exceptionCode = reply.readExceptionCode();
187
188 if (exceptionCode) {
189 return UNKNOWN_ERROR;
190 }
191
192 *uri = String8(reply.readString16());
193
194 return OK;
195 }
196
Andreas Huber1b86fe02014-01-29 11:13:26 -0800197private:
198 sp<IMemory> mMemory;
199};
200
201IMPLEMENT_META_INTERFACE(
202 MediaHTTPConnection, "android.media.IMediaHTTPConnection");
203
Glenn Kastend2027332015-03-20 08:59:18 -0700204} // namespace android