• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <media/stagefright/MediaErrors.h>
28 
29 namespace android {
30 
31 enum {
32     CONNECT = IBinder::FIRST_CALL_TRANSACTION,
33     DISCONNECT,
34     READ_AT,
35     GET_SIZE,
36     GET_MIME_TYPE,
37     GET_URI
38 };
39 
40 struct BpMediaHTTPConnection : public BpInterface<IMediaHTTPConnection> {
BpMediaHTTPConnectionandroid::BpMediaHTTPConnection41     explicit BpMediaHTTPConnection(const sp<IBinder> &impl)
42         : BpInterface<IMediaHTTPConnection>(impl) {
43     }
44 
connectandroid::BpMediaHTTPConnection45     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) {
73             return false;
74         }
75 
76         sp<IBinder> binder = reply.readStrongBinder();
77         mMemory = interface_cast<IMemory>(binder);
78 
79         return mMemory != NULL;
80     }
81 
disconnectandroid::BpMediaHTTPConnection82     virtual void disconnect() {
83         Parcel data, reply;
84         data.writeInterfaceToken(
85                 IMediaHTTPConnection::getInterfaceDescriptor());
86 
87         remote()->transact(DISCONNECT, data, &reply);
88     }
89 
readAtandroid::BpMediaHTTPConnection90     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);
99         if (err != OK) {
100             ALOGE("remote readAt failed");
101             return UNKNOWN_ERROR;
102         }
103 
104         int32_t exceptionCode = reply.readExceptionCode();
105 
106         if (exceptionCode) {
107             return UNKNOWN_ERROR;
108         }
109 
110         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;
118 
119         if (len > size) {
120             ALOGE("requested %zu, got %zu", size, len);
121             return ERROR_OUT_OF_RANGE;
122         }
123         if (len > mMemory->size()) {
124             ALOGE("got %zu, but memory has %zu", len, mMemory->size());
125             return ERROR_OUT_OF_RANGE;
126         }
127         if(buffer == NULL) {
128            ALOGE("readAt got a NULL buffer");
129            return UNKNOWN_ERROR;
130         }
131         if (mMemory->unsecurePointer() == NULL) {
132            ALOGE("readAt got a NULL mMemory->unsecurePointer()");
133            return UNKNOWN_ERROR;
134         }
135 
136         memcpy(buffer, mMemory->unsecurePointer(), len);
137 
138         return len;
139     }
140 
getSizeandroid::BpMediaHTTPConnection141     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 
getMIMETypeandroid::BpMediaHTTPConnection157     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 
getUriandroid::BpMediaHTTPConnection177     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 
197 private:
198     sp<IMemory> mMemory;
199 };
200 
201 IMPLEMENT_META_INTERFACE(
202         MediaHTTPConnection, "android.media.IMediaHTTPConnection");
203 
204 } // namespace android
205