blob: 7df3b655fd0386c3337a75a0f605ec908824a4f4 [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 Jia2a5e49c2016-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 Jia2a5e49c2016-07-07 10:02:51 -070038 DRM_INITIALIZATION,
Chris Watkins99f31602015-03-20 13:06:33 -070039};
40
41struct BpDataSource : public BpInterface<IDataSource> {
Chih-Hung Hsieh090ef602016-04-27 10:39:54 -070042 explicit BpDataSource(const sp<IBinder>& impl)
43 : BpInterface<IDataSource>(impl) {}
Chris Watkins99f31602015-03-20 13:06:33 -070044
45 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
53 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 remote()->transact(READ_AT, data, &reply);
59 return reply.readInt64();
60 }
61
62 virtual status_t getSize(off64_t* size) {
63 Parcel data, reply;
64 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
65 remote()->transact(GET_SIZE, data, &reply);
66 status_t err = reply.readInt32();
67 *size = reply.readInt64();
68 return err;
69 }
70
71 virtual void close() {
72 Parcel data, reply;
73 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
74 remote()->transact(CLOSE, data, &reply);
75 }
Wei Jia10551fc2016-01-27 14:26:51 -080076
77 virtual uint32_t getFlags() {
78 Parcel data, reply;
79 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
80 remote()->transact(GET_FLAGS, data, &reply);
81 return reply.readUint32();
82 }
Marco Nelissen69d3d8a2016-03-07 13:20:01 -080083
84 virtual String8 toString() {
85 Parcel data, reply;
86 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
87 remote()->transact(TO_STRING, data, &reply);
88 return reply.readString8();
89 }
Wei Jia2a5e49c2016-07-07 10:02:51 -070090
91 virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
92 Parcel data, reply;
93 data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
94 if (mime == NULL) {
95 data.writeInt32(0);
96 } else {
97 data.writeInt32(1);
98 data.writeCString(mime);
99 }
100 remote()->transact(DRM_INITIALIZATION, data, &reply);
101 sp<DecryptHandle> handle;
102 if (reply.dataAvail() != 0) {
103 handle = new DecryptHandle();
104 handle->decryptId = reply.readInt32();
105 handle->mimeType = reply.readString8();
106 handle->decryptApiType = reply.readInt32();
107 handle->status = reply.readInt32();
108
109 const int bufferLength = data.readInt32();
110 if (bufferLength != -1) {
111 handle->decryptInfo = new DecryptInfo();
112 handle->decryptInfo->decryptBufferLength = bufferLength;
113 }
114
115 size_t size = data.readInt32();
116 for (size_t i = 0; i < size; ++i) {
117 DrmCopyControl key = (DrmCopyControl)data.readInt32();
118 int value = data.readInt32();
119 handle->copyControlVector.add(key, value);
120 }
121
122 size = data.readInt32();
123 for (size_t i = 0; i < size; ++i) {
124 String8 key = data.readString8();
125 String8 value = data.readString8();
126 handle->extendedData.add(key, value);
127 }
128 }
129 return handle;
130 }
Chris Watkins99f31602015-03-20 13:06:33 -0700131};
132
133IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
134
135status_t BnDataSource::onTransact(
136 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
137 switch (code) {
138 case GET_IMEMORY: {
139 CHECK_INTERFACE(IDataSource, data, reply);
140 reply->writeStrongBinder(IInterface::asBinder(getIMemory()));
141 return NO_ERROR;
142 } break;
143 case READ_AT: {
144 CHECK_INTERFACE(IDataSource, data, reply);
145 off64_t offset = (off64_t) data.readInt64();
146 size_t size = (size_t) data.readInt64();
147 reply->writeInt64(readAt(offset, size));
148 return NO_ERROR;
149 } break;
150 case GET_SIZE: {
151 CHECK_INTERFACE(IDataSource, data, reply);
152 off64_t size;
153 status_t err = getSize(&size);
154 reply->writeInt32(err);
155 reply->writeInt64(size);
156 return NO_ERROR;
157 } break;
158 case CLOSE: {
159 CHECK_INTERFACE(IDataSource, data, reply);
160 close();
161 return NO_ERROR;
162 } break;
Wei Jia10551fc2016-01-27 14:26:51 -0800163 case GET_FLAGS: {
164 CHECK_INTERFACE(IDataSource, data, reply);
165 reply->writeUint32(getFlags());
166 return NO_ERROR;
167 } break;
Marco Nelissen69d3d8a2016-03-07 13:20:01 -0800168 case TO_STRING: {
169 CHECK_INTERFACE(IDataSource, data, reply);
170 reply->writeString8(toString());
171 return NO_ERROR;
172 } break;
Wei Jia2a5e49c2016-07-07 10:02:51 -0700173 case DRM_INITIALIZATION: {
174 CHECK_INTERFACE(IDataSource, data, reply);
175 const char *mime = NULL;
176 const int32_t flag = data.readInt32();
177 if (flag != 0) {
178 mime = data.readCString();
179 }
180 sp<DecryptHandle> handle = DrmInitialization(mime);
181 if (handle != NULL) {
182 reply->writeInt32(handle->decryptId);
183 reply->writeString8(handle->mimeType);
184 reply->writeInt32(handle->decryptApiType);
185 reply->writeInt32(handle->status);
186
187 if (handle->decryptInfo != NULL) {
188 reply->writeInt32(handle->decryptInfo->decryptBufferLength);
189 } else {
190 reply->writeInt32(-1);
191 }
192
193 size_t size = handle->copyControlVector.size();
194 reply->writeInt32(size);
195 for (size_t i = 0; i < size; ++i) {
196 reply->writeInt32(handle->copyControlVector.keyAt(i));
197 reply->writeInt32(handle->copyControlVector.valueAt(i));
198 }
199
200 size = handle->extendedData.size();
201 reply->writeInt32(size);
202 for (size_t i = 0; i < size; ++i) {
203 reply->writeString8(handle->extendedData.keyAt(i));
204 reply->writeString8(handle->extendedData.valueAt(i));
205 }
206 }
207 return NO_ERROR;
208 } break;
Marco Nelissen69d3d8a2016-03-07 13:20:01 -0800209
Chris Watkins99f31602015-03-20 13:06:33 -0700210 default:
211 return BBinder::onTransact(code, data, reply, flags);
212 }
213}
214
215} // namespace android