1 /*
2 * Copyright 2015 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 "IDataSource"
19 #include <utils/Log.h>
20 #include <utils/Timers.h>
21
22 #include <media/IDataSource.h>
23
24 #include <binder/IMemory.h>
25 #include <binder/Parcel.h>
26 #include <drm/drm_framework_common.h>
27 #include <media/stagefright/foundation/ADebug.h>
28
29 namespace android {
30
31 enum {
32 GET_IMEMORY = IBinder::FIRST_CALL_TRANSACTION,
33 READ_AT,
34 GET_SIZE,
35 CLOSE,
36 GET_FLAGS,
37 TO_STRING,
38 DRM_INITIALIZATION,
39 };
40
41 struct BpDataSource : public BpInterface<IDataSource> {
BpDataSourceandroid::BpDataSource42 explicit BpDataSource(const sp<IBinder>& impl)
43 : BpInterface<IDataSource>(impl) {}
44
getIMemoryandroid::BpDataSource45 virtual sp<IMemory> getIMemory() {
46 Parcel data, reply;
47 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
48 remote()->transact(GET_IMEMORY, data, &reply);
49 sp<IBinder> binder = reply.readStrongBinder();
50 return interface_cast<IMemory>(binder);
51 }
52
readAtandroid::BpDataSource53 virtual ssize_t readAt(off64_t offset, size_t size) {
54 Parcel data, reply;
55 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
56 data.writeInt64(offset);
57 data.writeInt64(size);
58 status_t err = remote()->transact(READ_AT, data, &reply);
59 if (err != OK) {
60 return err;
61 }
62 int64_t value = 0;
63 err = reply.readInt64(&value);
64 if (err != OK) {
65 return err;
66 }
67 return (ssize_t)value;
68 }
69
getSizeandroid::BpDataSource70 virtual status_t getSize(off64_t* size) {
71 Parcel data, reply;
72 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
73 remote()->transact(GET_SIZE, data, &reply);
74 status_t err = reply.readInt32();
75 *size = reply.readInt64();
76 return err;
77 }
78
closeandroid::BpDataSource79 virtual void close() {
80 Parcel data, reply;
81 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
82 remote()->transact(CLOSE, data, &reply);
83 }
84
getFlagsandroid::BpDataSource85 virtual uint32_t getFlags() {
86 Parcel data, reply;
87 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
88 remote()->transact(GET_FLAGS, data, &reply);
89 return reply.readUint32();
90 }
91
toStringandroid::BpDataSource92 virtual String8 toString() {
93 Parcel data, reply;
94 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
95 remote()->transact(TO_STRING, data, &reply);
96 return reply.readString8();
97 }
98
DrmInitializationandroid::BpDataSource99 virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
100 Parcel data, reply;
101 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
102 if (mime == NULL) {
103 data.writeInt32(0);
104 } else {
105 data.writeInt32(1);
106 data.writeCString(mime);
107 }
108 remote()->transact(DRM_INITIALIZATION, data, &reply);
109 sp<DecryptHandle> handle;
110 if (reply.dataAvail() != 0) {
111 handle = new DecryptHandle();
112 handle->decryptId = reply.readInt32();
113 handle->mimeType = reply.readString8();
114 handle->decryptApiType = reply.readInt32();
115 handle->status = reply.readInt32();
116
117 const int bufferLength = data.readInt32();
118 if (bufferLength != -1) {
119 handle->decryptInfo = new DecryptInfo();
120 handle->decryptInfo->decryptBufferLength = bufferLength;
121 }
122
123 size_t size = data.readInt32();
124 for (size_t i = 0; i < size; ++i) {
125 DrmCopyControl key = (DrmCopyControl)data.readInt32();
126 int value = data.readInt32();
127 handle->copyControlVector.add(key, value);
128 }
129
130 size = data.readInt32();
131 for (size_t i = 0; i < size; ++i) {
132 String8 key = data.readString8();
133 String8 value = data.readString8();
134 handle->extendedData.add(key, value);
135 }
136 }
137 return handle;
138 }
139 };
140
141 IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
142
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)143 status_t BnDataSource::onTransact(
144 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
145 switch (code) {
146 case GET_IMEMORY: {
147 CHECK_INTERFACE(IDataSource, data, reply);
148 reply->writeStrongBinder(IInterface::asBinder(getIMemory()));
149 return NO_ERROR;
150 } break;
151 case READ_AT: {
152 CHECK_INTERFACE(IDataSource, data, reply);
153 off64_t offset = (off64_t) data.readInt64();
154 size_t size = (size_t) data.readInt64();
155 reply->writeInt64(readAt(offset, size));
156 return NO_ERROR;
157 } break;
158 case GET_SIZE: {
159 CHECK_INTERFACE(IDataSource, data, reply);
160 off64_t size;
161 status_t err = getSize(&size);
162 reply->writeInt32(err);
163 reply->writeInt64(size);
164 return NO_ERROR;
165 } break;
166 case CLOSE: {
167 CHECK_INTERFACE(IDataSource, data, reply);
168 close();
169 return NO_ERROR;
170 } break;
171 case GET_FLAGS: {
172 CHECK_INTERFACE(IDataSource, data, reply);
173 reply->writeUint32(getFlags());
174 return NO_ERROR;
175 } break;
176 case TO_STRING: {
177 CHECK_INTERFACE(IDataSource, data, reply);
178 reply->writeString8(toString());
179 return NO_ERROR;
180 } break;
181 case DRM_INITIALIZATION: {
182 CHECK_INTERFACE(IDataSource, data, reply);
183 const char *mime = NULL;
184 const int32_t flag = data.readInt32();
185 if (flag != 0) {
186 mime = data.readCString();
187 }
188 sp<DecryptHandle> handle = DrmInitialization(mime);
189 if (handle != NULL) {
190 reply->writeInt32(handle->decryptId);
191 reply->writeString8(handle->mimeType);
192 reply->writeInt32(handle->decryptApiType);
193 reply->writeInt32(handle->status);
194
195 if (handle->decryptInfo != NULL) {
196 reply->writeInt32(handle->decryptInfo->decryptBufferLength);
197 } else {
198 reply->writeInt32(-1);
199 }
200
201 size_t size = handle->copyControlVector.size();
202 reply->writeInt32(size);
203 for (size_t i = 0; i < size; ++i) {
204 reply->writeInt32(handle->copyControlVector.keyAt(i));
205 reply->writeInt32(handle->copyControlVector.valueAt(i));
206 }
207
208 size = handle->extendedData.size();
209 reply->writeInt32(size);
210 for (size_t i = 0; i < size; ++i) {
211 reply->writeString8(handle->extendedData.keyAt(i));
212 reply->writeString8(handle->extendedData.valueAt(i));
213 }
214 }
215 return NO_ERROR;
216 } break;
217
218 default:
219 return BBinder::onTransact(code, data, reply, flags);
220 }
221 }
222
223 } // namespace android
224