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 BpDataSource(const sp<IBinder>& impl) : BpInterface<IDataSource>(impl) {}
43
getIMemoryandroid::BpDataSource44 virtual sp<IMemory> getIMemory() {
45 Parcel data, reply;
46 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
47 remote()->transact(GET_IMEMORY, data, &reply);
48 sp<IBinder> binder = reply.readStrongBinder();
49 return interface_cast<IMemory>(binder);
50 }
51
readAtandroid::BpDataSource52 virtual ssize_t readAt(off64_t offset, size_t size) {
53 Parcel data, reply;
54 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
55 data.writeInt64(offset);
56 data.writeInt64(size);
57 remote()->transact(READ_AT, data, &reply);
58 return reply.readInt64();
59 }
60
getSizeandroid::BpDataSource61 virtual status_t getSize(off64_t* size) {
62 Parcel data, reply;
63 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
64 remote()->transact(GET_SIZE, data, &reply);
65 status_t err = reply.readInt32();
66 *size = reply.readInt64();
67 return err;
68 }
69
closeandroid::BpDataSource70 virtual void close() {
71 Parcel data, reply;
72 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
73 remote()->transact(CLOSE, data, &reply);
74 }
75
getFlagsandroid::BpDataSource76 virtual uint32_t getFlags() {
77 Parcel data, reply;
78 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
79 remote()->transact(GET_FLAGS, data, &reply);
80 return reply.readUint32();
81 }
82
toStringandroid::BpDataSource83 virtual String8 toString() {
84 Parcel data, reply;
85 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
86 remote()->transact(TO_STRING, data, &reply);
87 return reply.readString8();
88 }
89
DrmInitializationandroid::BpDataSource90 virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
91 Parcel data, reply;
92 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
93 if (mime == NULL) {
94 data.writeInt32(0);
95 } else {
96 data.writeInt32(1);
97 data.writeCString(mime);
98 }
99 remote()->transact(DRM_INITIALIZATION, data, &reply);
100 sp<DecryptHandle> handle;
101 if (reply.dataAvail() != 0) {
102 handle = new DecryptHandle();
103 handle->decryptId = reply.readInt32();
104 handle->mimeType = reply.readString8();
105 handle->decryptApiType = reply.readInt32();
106 handle->status = reply.readInt32();
107
108 const int bufferLength = data.readInt32();
109 if (bufferLength != -1) {
110 handle->decryptInfo = new DecryptInfo();
111 handle->decryptInfo->decryptBufferLength = bufferLength;
112 }
113
114 size_t size = data.readInt32();
115 for (size_t i = 0; i < size; ++i) {
116 DrmCopyControl key = (DrmCopyControl)data.readInt32();
117 int value = data.readInt32();
118 handle->copyControlVector.add(key, value);
119 }
120
121 size = data.readInt32();
122 for (size_t i = 0; i < size; ++i) {
123 String8 key = data.readString8();
124 String8 value = data.readString8();
125 handle->extendedData.add(key, value);
126 }
127 }
128 return handle;
129 }
130 };
131
132 IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
133
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)134 status_t BnDataSource::onTransact(
135 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
136 switch (code) {
137 case GET_IMEMORY: {
138 CHECK_INTERFACE(IDataSource, data, reply);
139 reply->writeStrongBinder(IInterface::asBinder(getIMemory()));
140 return NO_ERROR;
141 } break;
142 case READ_AT: {
143 CHECK_INTERFACE(IDataSource, data, reply);
144 off64_t offset = (off64_t) data.readInt64();
145 size_t size = (size_t) data.readInt64();
146 reply->writeInt64(readAt(offset, size));
147 return NO_ERROR;
148 } break;
149 case GET_SIZE: {
150 CHECK_INTERFACE(IDataSource, data, reply);
151 off64_t size;
152 status_t err = getSize(&size);
153 reply->writeInt32(err);
154 reply->writeInt64(size);
155 return NO_ERROR;
156 } break;
157 case CLOSE: {
158 CHECK_INTERFACE(IDataSource, data, reply);
159 close();
160 return NO_ERROR;
161 } break;
162 case GET_FLAGS: {
163 CHECK_INTERFACE(IDataSource, data, reply);
164 reply->writeUint32(getFlags());
165 return NO_ERROR;
166 } break;
167 case TO_STRING: {
168 CHECK_INTERFACE(IDataSource, data, reply);
169 reply->writeString8(toString());
170 return NO_ERROR;
171 } break;
172 case DRM_INITIALIZATION: {
173 CHECK_INTERFACE(IDataSource, data, reply);
174 const char *mime = NULL;
175 const int32_t flag = data.readInt32();
176 if (flag != 0) {
177 mime = data.readCString();
178 }
179 sp<DecryptHandle> handle = DrmInitialization(mime);
180 if (handle != NULL) {
181 reply->writeInt32(handle->decryptId);
182 reply->writeString8(handle->mimeType);
183 reply->writeInt32(handle->decryptApiType);
184 reply->writeInt32(handle->status);
185
186 if (handle->decryptInfo != NULL) {
187 reply->writeInt32(handle->decryptInfo->decryptBufferLength);
188 } else {
189 reply->writeInt32(-1);
190 }
191
192 size_t size = handle->copyControlVector.size();
193 reply->writeInt32(size);
194 for (size_t i = 0; i < size; ++i) {
195 reply->writeInt32(handle->copyControlVector.keyAt(i));
196 reply->writeInt32(handle->copyControlVector.valueAt(i));
197 }
198
199 size = handle->extendedData.size();
200 reply->writeInt32(size);
201 for (size_t i = 0; i < size; ++i) {
202 reply->writeString8(handle->extendedData.keyAt(i));
203 reply->writeString8(handle->extendedData.valueAt(i));
204 }
205 }
206 return NO_ERROR;
207 } break;
208
209 default:
210 return BBinder::onTransact(code, data, reply, flags);
211 }
212 }
213
214 } // namespace android
215