blob: 5ad39fe81c3ade315ff3b96449d6f75a95e37722 [file] [log] [blame]
Chris Watkins99f31602015-03-20 13:06:33 -07001/*
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>
Wei Jia9a1a9532016-07-07 10:02:51 -070026#include <drm/drm_framework_common.h>
Chris Watkins99f31602015-03-20 13:06:33 -070027#include <media/stagefright/foundation/ADebug.h>
28
29namespace android {
30
31enum {
32 GET_IMEMORY = IBinder::FIRST_CALL_TRANSACTION,
33 READ_AT,
34 GET_SIZE,
35 CLOSE,
Wei Jia10551fc2016-01-27 14:26:51 -080036 GET_FLAGS,
Marco Nelissen69d3d8a2016-03-07 13:20:01 -080037 TO_STRING,
Wei Jia9a1a9532016-07-07 10:02:51 -070038 DRM_INITIALIZATION,
Chris Watkins99f31602015-03-20 13:06:33 -070039};
40
41struct BpDataSource : public BpInterface<IDataSource> {
42 BpDataSource(const sp<IBinder>& impl) : BpInterface<IDataSource>(impl) {}
43
44 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
52 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);
Wei Jia37156122017-02-14 17:07:24 -080057 status_t err = remote()->transact(READ_AT, data, &reply);
58 if (err != OK) {
59 return err;
60 }
61 int64_t value = 0;
62 err = reply.readInt64(&value);
63 if (err != OK) {
64 return err;
65 }
66 return (ssize_t)value;
Chris Watkins99f31602015-03-20 13:06:33 -070067 }
68
69 virtual status_t getSize(off64_t* size) {
70 Parcel data, reply;
71 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
72 remote()->transact(GET_SIZE, data, &reply);
73 status_t err = reply.readInt32();
74 *size = reply.readInt64();
75 return err;
76 }
77
78 virtual void close() {
79 Parcel data, reply;
80 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
81 remote()->transact(CLOSE, data, &reply);
82 }
Wei Jia10551fc2016-01-27 14:26:51 -080083
84 virtual uint32_t getFlags() {
85 Parcel data, reply;
86 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
87 remote()->transact(GET_FLAGS, data, &reply);
88 return reply.readUint32();
89 }
Marco Nelissen69d3d8a2016-03-07 13:20:01 -080090
91 virtual String8 toString() {
92 Parcel data, reply;
93 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
94 remote()->transact(TO_STRING, data, &reply);
95 return reply.readString8();
96 }
Wei Jia9a1a9532016-07-07 10:02:51 -070097
98 virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
99 Parcel data, reply;
100 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
101 if (mime == NULL) {
102 data.writeInt32(0);
103 } else {
104 data.writeInt32(1);
105 data.writeCString(mime);
106 }
107 remote()->transact(DRM_INITIALIZATION, data, &reply);
108 sp<DecryptHandle> handle;
109 if (reply.dataAvail() != 0) {
110 handle = new DecryptHandle();
111 handle->decryptId = reply.readInt32();
112 handle->mimeType = reply.readString8();
113 handle->decryptApiType = reply.readInt32();
114 handle->status = reply.readInt32();
115
116 const int bufferLength = data.readInt32();
117 if (bufferLength != -1) {
118 handle->decryptInfo = new DecryptInfo();
119 handle->decryptInfo->decryptBufferLength = bufferLength;
120 }
121
122 size_t size = data.readInt32();
123 for (size_t i = 0; i < size; ++i) {
124 DrmCopyControl key = (DrmCopyControl)data.readInt32();
125 int value = data.readInt32();
126 handle->copyControlVector.add(key, value);
127 }
128
129 size = data.readInt32();
130 for (size_t i = 0; i < size; ++i) {
131 String8 key = data.readString8();
132 String8 value = data.readString8();
133 handle->extendedData.add(key, value);
134 }
135 }
136 return handle;
137 }
Chris Watkins99f31602015-03-20 13:06:33 -0700138};
139
140IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
141
142status_t BnDataSource::onTransact(
143 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
144 switch (code) {
145 case GET_IMEMORY: {
146 CHECK_INTERFACE(IDataSource, data, reply);
147 reply->writeStrongBinder(IInterface::asBinder(getIMemory()));
148 return NO_ERROR;
149 } break;
150 case READ_AT: {
151 CHECK_INTERFACE(IDataSource, data, reply);
152 off64_t offset = (off64_t) data.readInt64();
153 size_t size = (size_t) data.readInt64();
154 reply->writeInt64(readAt(offset, size));
155 return NO_ERROR;
156 } break;
157 case GET_SIZE: {
158 CHECK_INTERFACE(IDataSource, data, reply);
159 off64_t size;
160 status_t err = getSize(&size);
161 reply->writeInt32(err);
162 reply->writeInt64(size);
163 return NO_ERROR;
164 } break;
165 case CLOSE: {
166 CHECK_INTERFACE(IDataSource, data, reply);
167 close();
168 return NO_ERROR;
169 } break;
Wei Jia10551fc2016-01-27 14:26:51 -0800170 case GET_FLAGS: {
171 CHECK_INTERFACE(IDataSource, data, reply);
172 reply->writeUint32(getFlags());
173 return NO_ERROR;
174 } break;
Marco Nelissen69d3d8a2016-03-07 13:20:01 -0800175 case TO_STRING: {
176 CHECK_INTERFACE(IDataSource, data, reply);
177 reply->writeString8(toString());
178 return NO_ERROR;
179 } break;
Wei Jia9a1a9532016-07-07 10:02:51 -0700180 case DRM_INITIALIZATION: {
181 CHECK_INTERFACE(IDataSource, data, reply);
182 const char *mime = NULL;
183 const int32_t flag = data.readInt32();
184 if (flag != 0) {
185 mime = data.readCString();
186 }
187 sp<DecryptHandle> handle = DrmInitialization(mime);
188 if (handle != NULL) {
189 reply->writeInt32(handle->decryptId);
190 reply->writeString8(handle->mimeType);
191 reply->writeInt32(handle->decryptApiType);
192 reply->writeInt32(handle->status);
193
194 if (handle->decryptInfo != NULL) {
195 reply->writeInt32(handle->decryptInfo->decryptBufferLength);
196 } else {
197 reply->writeInt32(-1);
198 }
199
200 size_t size = handle->copyControlVector.size();
201 reply->writeInt32(size);
202 for (size_t i = 0; i < size; ++i) {
203 reply->writeInt32(handle->copyControlVector.keyAt(i));
204 reply->writeInt32(handle->copyControlVector.valueAt(i));
205 }
206
207 size = handle->extendedData.size();
208 reply->writeInt32(size);
209 for (size_t i = 0; i < size; ++i) {
210 reply->writeString8(handle->extendedData.keyAt(i));
211 reply->writeString8(handle->extendedData.valueAt(i));
212 }
213 }
214 return NO_ERROR;
215 } break;
Marco Nelissen69d3d8a2016-03-07 13:20:01 -0800216
Chris Watkins99f31602015-03-20 13:06:33 -0700217 default:
218 return BBinder::onTransact(code, data, reply, flags);
219 }
220}
221
222} // namespace android