IDrmManagerService.cpp revision 2151d8f9ae667c53749e81a93f0ec0c60f3b8e05
1/*
2 * Copyright (C) 2010 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 "IDrmManagerService(Native)"
19#include <utils/Log.h>
20
21#include <stdint.h>
22#include <sys/types.h>
23#include <binder/IPCThreadState.h>
24
25#include <drm/DrmInfo.h>
26#include <drm/DrmConstraints.h>
27#include <drm/DrmMetadata.h>
28#include <drm/DrmRights.h>
29#include <drm/DrmInfoStatus.h>
30#include <drm/DrmConvertedStatus.h>
31#include <drm/DrmInfoRequest.h>
32#include <drm/DrmSupportInfo.h>
33
34#include "IDrmManagerService.h"
35
36#define INVALID_BUFFER_LENGTH -1
37#define MAX_BINDER_TRANSACTION_SIZE ((1*1024*1024)-(4096*2))
38
39using namespace android;
40
41static void writeDecryptHandleToParcelData(
42        const DecryptHandle* handle, Parcel* data) {
43    data->writeInt32(handle->decryptId);
44    data->writeString8(handle->mimeType);
45    data->writeInt32(handle->decryptApiType);
46    data->writeInt32(handle->status);
47
48    int size = handle->copyControlVector.size();
49    data->writeInt32(size);
50    for (int i = 0; i < size; i++) {
51        data->writeInt32(handle->copyControlVector.keyAt(i));
52        data->writeInt32(handle->copyControlVector.valueAt(i));
53    }
54
55    size = handle->extendedData.size();
56    data->writeInt32(size);
57    for (int i = 0; i < size; i++) {
58        data->writeString8(handle->extendedData.keyAt(i));
59        data->writeString8(handle->extendedData.valueAt(i));
60    }
61
62    if (NULL != handle->decryptInfo) {
63        data->writeInt32(handle->decryptInfo->decryptBufferLength);
64    } else {
65        data->writeInt32(INVALID_BUFFER_LENGTH);
66    }
67}
68
69static void readDecryptHandleFromParcelData(
70        DecryptHandle* handle, const Parcel& data) {
71    if (0 == data.dataAvail()) {
72        return;
73    }
74
75    handle->decryptId = data.readInt32();
76    handle->mimeType = data.readString8();
77    handle->decryptApiType = data.readInt32();
78    handle->status = data.readInt32();
79
80    int size = data.readInt32();
81    for (int i = 0; i < size; i++) {
82        DrmCopyControl key = (DrmCopyControl)data.readInt32();
83        int value = data.readInt32();
84        handle->copyControlVector.add(key, value);
85    }
86
87    size = data.readInt32();
88    for (int i = 0; i < size; i++) {
89        String8 key = data.readString8();
90        String8 value = data.readString8();
91        handle->extendedData.add(key, value);
92    }
93
94    handle->decryptInfo = NULL;
95    const int bufferLen = data.readInt32();
96    if (INVALID_BUFFER_LENGTH != bufferLen) {
97        handle->decryptInfo = new DecryptInfo();
98        handle->decryptInfo->decryptBufferLength = bufferLen;
99    }
100}
101
102static void clearDecryptHandle(DecryptHandle* handle) {
103    if (handle == NULL) {
104        return;
105    }
106    if (handle->decryptInfo) {
107        delete handle->decryptInfo;
108        handle->decryptInfo = NULL;
109    }
110    handle->copyControlVector.clear();
111    handle->extendedData.clear();
112}
113
114int BpDrmManagerService::addUniqueId(bool isNative) {
115    ALOGV("add uniqueid");
116    Parcel data, reply;
117    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
118    data.writeInt32(isNative);
119    remote()->transact(ADD_UNIQUEID, data, &reply);
120    return reply.readInt32();
121}
122
123void BpDrmManagerService::removeUniqueId(int uniqueId) {
124    ALOGV("remove uniqueid");
125    Parcel data, reply;
126    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
127    data.writeInt32(uniqueId);
128    remote()->transact(REMOVE_UNIQUEID, data, &reply);
129}
130
131void BpDrmManagerService::addClient(int uniqueId) {
132    Parcel data, reply;
133    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
134    data.writeInt32(uniqueId);
135    remote()->transact(ADD_CLIENT, data, &reply);
136}
137
138void BpDrmManagerService::removeClient(int uniqueId) {
139    Parcel data, reply;
140    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
141    data.writeInt32(uniqueId);
142    remote()->transact(REMOVE_CLIENT, data, &reply);
143}
144
145status_t BpDrmManagerService::setDrmServiceListener(
146            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
147    ALOGV("setDrmServiceListener");
148    Parcel data, reply;
149
150    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
151    data.writeInt32(uniqueId);
152    data.writeStrongBinder(IInterface::asBinder(drmServiceListener));
153    remote()->transact(SET_DRM_SERVICE_LISTENER, data, &reply);
154    return reply.readInt32();
155}
156
157DrmConstraints* BpDrmManagerService::getConstraints(
158            int uniqueId, const String8* path, const int action) {
159    ALOGV("Get Constraints");
160    Parcel data, reply;
161
162    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
163    data.writeInt32(uniqueId);
164    data.writeString8(*path);
165    data.writeInt32(action);
166
167    remote()->transact(GET_CONSTRAINTS_FROM_CONTENT, data, &reply);
168
169    DrmConstraints* drmConstraints = NULL;
170    if (0 != reply.dataAvail()) {
171        //Filling Drm Constraints
172        drmConstraints = new DrmConstraints();
173
174        const int size = reply.readInt32();
175        for (int index = 0; index < size; ++index) {
176            const String8 key(reply.readString8());
177            const int bufferSize = reply.readInt32();
178            char* data = NULL;
179            if (0 < bufferSize) {
180                data = new char[bufferSize];
181                reply.read(data, bufferSize);
182                drmConstraints->put(&key, data);
183                delete[] data;
184            }
185        }
186    }
187    return drmConstraints;
188}
189
190DrmMetadata* BpDrmManagerService::getMetadata(int uniqueId, const String8* path) {
191    ALOGV("Get Metadata");
192    Parcel data, reply;
193    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
194    data.writeInt32(uniqueId);
195
196    DrmMetadata* drmMetadata = NULL;
197    data.writeString8(*path);
198    remote()->transact(GET_METADATA_FROM_CONTENT, data, &reply);
199
200    if (0 != reply.dataAvail()) {
201        //Filling Drm Metadata
202        drmMetadata = new DrmMetadata();
203
204        const int size = reply.readInt32();
205        for (int index = 0; index < size; ++index) {
206            const String8 key(reply.readString8());
207            const int bufferSize = reply.readInt32();
208            char* data = NULL;
209            if (0 < bufferSize) {
210                data = new char[bufferSize];
211                reply.read(data, bufferSize);
212                drmMetadata->put(&key, data);
213                delete[] data;
214            }
215        }
216    }
217    return drmMetadata;
218}
219
220bool BpDrmManagerService::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
221    ALOGV("Can Handle");
222    Parcel data, reply;
223
224    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
225    data.writeInt32(uniqueId);
226
227    data.writeString8(path);
228    data.writeString8(mimeType);
229
230    remote()->transact(CAN_HANDLE, data, &reply);
231
232    return static_cast<bool>(reply.readInt32());
233}
234
235DrmInfoStatus* BpDrmManagerService::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
236    ALOGV("Process DRM Info");
237    Parcel data, reply;
238
239    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
240    data.writeInt32(uniqueId);
241
242    //Filling DRM info
243    data.writeInt32(drmInfo->getInfoType());
244    const DrmBuffer dataBuffer = drmInfo->getData();
245    const int dataBufferSize = dataBuffer.length;
246    data.writeInt32(dataBufferSize);
247    if (0 < dataBufferSize) {
248        data.write(dataBuffer.data, dataBufferSize);
249    }
250    data.writeString8(drmInfo->getMimeType());
251
252    data.writeInt32(drmInfo->getCount());
253    DrmInfo::KeyIterator keyIt = drmInfo->keyIterator();
254
255    while (keyIt.hasNext()) {
256        const String8 key = keyIt.next();
257        data.writeString8(key);
258        const String8 value = drmInfo->get(key);
259        data.writeString8((value == String8("")) ? String8("NULL") : value);
260    }
261
262    remote()->transact(PROCESS_DRM_INFO, data, &reply);
263
264    DrmInfoStatus* drmInfoStatus = NULL;
265    if (0 != reply.dataAvail()) {
266        //Filling DRM Info Status
267        const int statusCode = reply.readInt32();
268        const int infoType = reply.readInt32();
269        const String8 mimeType = reply.readString8();
270
271        DrmBuffer* drmBuffer = NULL;
272        if (0 != reply.dataAvail()) {
273            const int bufferSize = reply.readInt32();
274            char* data = NULL;
275            if (0 < bufferSize) {
276                data = new char[bufferSize];
277                reply.read(data, bufferSize);
278            }
279            drmBuffer = new DrmBuffer(data, bufferSize);
280        }
281        drmInfoStatus = new DrmInfoStatus(statusCode, infoType, drmBuffer, mimeType);
282    }
283    return drmInfoStatus;
284}
285
286DrmInfo* BpDrmManagerService::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) {
287    ALOGV("Acquire DRM Info");
288    Parcel data, reply;
289
290    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
291    data.writeInt32(uniqueId);
292
293    //Filling DRM Info Request
294    data.writeInt32(drmInforequest->getInfoType());
295    data.writeString8(drmInforequest->getMimeType());
296
297    data.writeInt32(drmInforequest->getCount());
298    DrmInfoRequest::KeyIterator keyIt = drmInforequest->keyIterator();
299
300    while (keyIt.hasNext()) {
301        const String8 key = keyIt.next();
302        data.writeString8(key);
303        const String8 value = drmInforequest->get(key);
304        if (key == String8("FileDescriptorKey")) {
305            int fd = -1;
306            sscanf(value.string(), "FileDescriptor[%d]", &fd);
307            data.writeFileDescriptor(fd);
308        } else {
309            data.writeString8((value == String8("")) ? String8("NULL") : value);
310        }
311    }
312
313    remote()->transact(ACQUIRE_DRM_INFO, data, &reply);
314
315    DrmInfo* drmInfo = NULL;
316    if (0 != reply.dataAvail()) {
317        //Filling DRM Info
318        const int infoType = reply.readInt32();
319        const int bufferSize = reply.readInt32();
320        char* data = NULL;
321
322        if (0 < bufferSize) {
323            data = new char[bufferSize];
324            reply.read(data, bufferSize);
325        }
326        drmInfo = new DrmInfo(infoType, DrmBuffer(data, bufferSize), reply.readString8());
327
328        const int size = reply.readInt32();
329        for (int index = 0; index < size; ++index) {
330            const String8 key(reply.readString8());
331            const String8 value(reply.readString8());
332            drmInfo->put(key, (value == String8("NULL")) ? String8("") : value);
333        }
334    }
335    return drmInfo;
336}
337
338status_t BpDrmManagerService::saveRights(
339            int uniqueId, const DrmRights& drmRights,
340            const String8& rightsPath, const String8& contentPath) {
341    ALOGV("Save Rights");
342    Parcel data, reply;
343
344    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
345    data.writeInt32(uniqueId);
346
347    //Filling Drm Rights
348    const DrmBuffer dataBuffer = drmRights.getData();
349    data.writeInt32(dataBuffer.length);
350    data.write(dataBuffer.data, dataBuffer.length);
351
352    const String8 mimeType = drmRights.getMimeType();
353    data.writeString8((mimeType == String8("")) ? String8("NULL") : mimeType);
354
355    const String8 accountId = drmRights.getAccountId();
356    data.writeString8((accountId == String8("")) ? String8("NULL") : accountId);
357
358    const String8 subscriptionId = drmRights.getSubscriptionId();
359    data.writeString8((subscriptionId == String8("")) ? String8("NULL") : subscriptionId);
360
361    data.writeString8((rightsPath == String8("")) ? String8("NULL") : rightsPath);
362    data.writeString8((contentPath == String8("")) ? String8("NULL") : contentPath);
363
364    remote()->transact(SAVE_RIGHTS, data, &reply);
365    return reply.readInt32();
366}
367
368String8 BpDrmManagerService::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
369    ALOGV("Get Original MimeType");
370    Parcel data, reply;
371
372    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
373    data.writeInt32(uniqueId);
374    data.writeString8(path);
375    int32_t isFdValid = (fd >= 0);
376    data.writeInt32(isFdValid);
377    if (isFdValid) {
378        data.writeFileDescriptor(fd);
379    }
380
381    remote()->transact(GET_ORIGINAL_MIMETYPE, data, &reply);
382    return reply.readString8();
383}
384
385int BpDrmManagerService::getDrmObjectType(
386            int uniqueId, const String8& path, const String8& mimeType) {
387    ALOGV("Get Drm object type");
388    Parcel data, reply;
389
390    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
391    data.writeInt32(uniqueId);
392    data.writeString8(path);
393    data.writeString8(mimeType);
394
395    remote()->transact(GET_DRM_OBJECT_TYPE, data, &reply);
396
397    return reply.readInt32();
398}
399
400int BpDrmManagerService::checkRightsStatus(int uniqueId, const String8& path, int action) {
401    ALOGV("checkRightsStatus");
402    Parcel data, reply;
403
404    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
405    data.writeInt32(uniqueId);
406    data.writeString8(path);
407    data.writeInt32(action);
408
409    remote()->transact(CHECK_RIGHTS_STATUS, data, &reply);
410
411    return reply.readInt32();
412}
413
414status_t BpDrmManagerService::consumeRights(
415            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
416    ALOGV("consumeRights");
417    Parcel data, reply;
418
419    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
420    data.writeInt32(uniqueId);
421
422    writeDecryptHandleToParcelData(decryptHandle, &data);
423
424    data.writeInt32(action);
425    data.writeInt32(static_cast< int>(reserve));
426
427    remote()->transact(CONSUME_RIGHTS, data, &reply);
428    return reply.readInt32();
429}
430
431status_t BpDrmManagerService::setPlaybackStatus(
432            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
433    ALOGV("setPlaybackStatus");
434    Parcel data, reply;
435
436    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
437    data.writeInt32(uniqueId);
438
439    writeDecryptHandleToParcelData(decryptHandle, &data);
440
441    data.writeInt32(playbackStatus);
442    data.writeInt64(position);
443
444    remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
445    return reply.readInt32();
446}
447
448bool BpDrmManagerService::validateAction(
449            int uniqueId, const String8& path,
450            int action, const ActionDescription& description) {
451    ALOGV("validateAction");
452    Parcel data, reply;
453
454    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
455    data.writeInt32(uniqueId);
456    data.writeString8(path);
457    data.writeInt32(action);
458    data.writeInt32(description.outputType);
459    data.writeInt32(description.configuration);
460
461    remote()->transact(VALIDATE_ACTION, data, &reply);
462
463    return static_cast<bool>(reply.readInt32());
464}
465
466status_t BpDrmManagerService::removeRights(int uniqueId, const String8& path) {
467    ALOGV("removeRights");
468    Parcel data, reply;
469
470    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
471    data.writeInt32(uniqueId);
472    data.writeString8(path);
473
474    remote()->transact(REMOVE_RIGHTS, data, &reply);
475    return reply.readInt32();
476}
477
478status_t BpDrmManagerService::removeAllRights(int uniqueId) {
479    ALOGV("removeAllRights");
480    Parcel data, reply;
481
482    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
483    data.writeInt32(uniqueId);
484
485    remote()->transact(REMOVE_ALL_RIGHTS, data, &reply);
486    return reply.readInt32();
487}
488
489int BpDrmManagerService::openConvertSession(int uniqueId, const String8& mimeType) {
490    ALOGV("openConvertSession");
491    Parcel data, reply;
492
493    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
494    data.writeInt32(uniqueId);
495    data.writeString8(mimeType);
496
497    remote()->transact(OPEN_CONVERT_SESSION, data, &reply);
498    return reply.readInt32();
499}
500
501DrmConvertedStatus* BpDrmManagerService::convertData(
502            int uniqueId, int convertId, const DrmBuffer* inputData) {
503    ALOGV("convertData");
504    Parcel data, reply;
505
506    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
507    data.writeInt32(uniqueId);
508    data.writeInt32(convertId);
509    data.writeInt32(inputData->length);
510    data.write(inputData->data, inputData->length);
511
512    remote()->transact(CONVERT_DATA, data, &reply);
513
514    DrmConvertedStatus* drmConvertedStatus = NULL;
515
516    if (0 != reply.dataAvail()) {
517        //Filling DRM Converted Status
518        const int statusCode = reply.readInt32();
519        const off64_t offset = reply.readInt64();
520
521        DrmBuffer* convertedData = NULL;
522        if (0 != reply.dataAvail()) {
523            const int bufferSize = reply.readInt32();
524            char* data = NULL;
525            if (0 < bufferSize) {
526                data = new char[bufferSize];
527                reply.read(data, bufferSize);
528            }
529            convertedData = new DrmBuffer(data, bufferSize);
530        }
531        drmConvertedStatus = new DrmConvertedStatus(statusCode, convertedData, offset);
532    }
533    return drmConvertedStatus;
534}
535
536DrmConvertedStatus* BpDrmManagerService::closeConvertSession(int uniqueId, int convertId) {
537    ALOGV("closeConvertSession");
538    Parcel data, reply;
539
540    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
541    data.writeInt32(uniqueId);
542    data.writeInt32(convertId);
543
544    remote()->transact(CLOSE_CONVERT_SESSION, data, &reply);
545
546    DrmConvertedStatus* drmConvertedStatus = NULL;
547
548    if (0 != reply.dataAvail()) {
549        //Filling DRM Converted Status
550        const int statusCode = reply.readInt32();
551        const off64_t offset = reply.readInt64();
552
553        DrmBuffer* convertedData = NULL;
554        if (0 != reply.dataAvail()) {
555            const int bufferSize = reply.readInt32();
556            char* data = NULL;
557            if (0 < bufferSize) {
558                data = new char[bufferSize];
559                reply.read(data, bufferSize);
560            }
561            convertedData = new DrmBuffer(data, bufferSize);
562        }
563        drmConvertedStatus = new DrmConvertedStatus(statusCode, convertedData, offset);
564    }
565    return drmConvertedStatus;
566}
567
568status_t BpDrmManagerService::getAllSupportInfo(
569            int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
570    ALOGV("Get All Support Info");
571    Parcel data, reply;
572
573    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
574    data.writeInt32(uniqueId);
575
576    remote()->transact(GET_ALL_SUPPORT_INFO, data, &reply);
577
578    //Filling DRM Support Info
579    const int arraySize = reply.readInt32();
580    if (0 < arraySize) {
581        *drmSupportInfoArray = new DrmSupportInfo[arraySize];
582
583        for (int index = 0; index < arraySize; ++index) {
584            DrmSupportInfo drmSupportInfo;
585
586            const int fileSuffixVectorSize = reply.readInt32();
587            for (int i = 0; i < fileSuffixVectorSize; ++i) {
588                drmSupportInfo.addFileSuffix(reply.readString8());
589            }
590
591            const int mimeTypeVectorSize = reply.readInt32();
592            for (int i = 0; i < mimeTypeVectorSize; ++i) {
593                drmSupportInfo.addMimeType(reply.readString8());
594            }
595
596            drmSupportInfo.setDescription(reply.readString8());
597            (*drmSupportInfoArray)[index] = drmSupportInfo;
598        }
599    }
600    *length = arraySize;
601    return reply.readInt32();
602}
603
604DecryptHandle* BpDrmManagerService::openDecryptSession(
605            int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
606    ALOGV("Entering BpDrmManagerService::openDecryptSession");
607    Parcel data, reply;
608
609    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
610    data.writeInt32(uniqueId);
611    data.writeFileDescriptor(fd);
612    data.writeInt64(offset);
613    data.writeInt64(length);
614    String8 mimeType;
615    if (mime) {
616        mimeType = mime;
617    }
618    data.writeString8(mimeType);
619
620    remote()->transact(OPEN_DECRYPT_SESSION, data, &reply);
621
622    DecryptHandle* handle = NULL;
623    if (0 != reply.dataAvail()) {
624        handle = new DecryptHandle();
625        readDecryptHandleFromParcelData(handle, reply);
626    }
627    return handle;
628}
629
630DecryptHandle* BpDrmManagerService::openDecryptSession(
631        int uniqueId, const char* uri, const char* mime) {
632
633    ALOGV("Entering BpDrmManagerService::openDecryptSession: mime=%s", mime? mime: "NULL");
634    Parcel data, reply;
635
636    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
637    data.writeInt32(uniqueId);
638    data.writeString8(String8(uri));
639    String8 mimeType;
640    if (mime) {
641        mimeType = mime;
642    }
643    data.writeString8(mimeType);
644
645    remote()->transact(OPEN_DECRYPT_SESSION_FROM_URI, data, &reply);
646
647    DecryptHandle* handle = NULL;
648    if (0 != reply.dataAvail()) {
649        handle = new DecryptHandle();
650        readDecryptHandleFromParcelData(handle, reply);
651    } else {
652        ALOGV("no decryptHandle is generated in service side");
653    }
654    return handle;
655}
656
657DecryptHandle* BpDrmManagerService::openDecryptSession(
658            int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
659    ALOGV("Entering BpDrmManagerService::openDecryptSession");
660    Parcel data, reply;
661
662    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
663    data.writeInt32(uniqueId);
664    if (buf.data != NULL && buf.length > 0) {
665        data.writeInt32(buf.length);
666        data.write(buf.data, buf.length);
667    } else {
668        data.writeInt32(0);
669    }
670    data.writeString8(mimeType);
671
672    remote()->transact(OPEN_DECRYPT_SESSION_FOR_STREAMING, data, &reply);
673
674    DecryptHandle* handle = NULL;
675    if (0 != reply.dataAvail()) {
676        handle = new DecryptHandle();
677        readDecryptHandleFromParcelData(handle, reply);
678    } else {
679        ALOGV("no decryptHandle is generated in service side");
680    }
681    return handle;
682}
683
684status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
685    ALOGV("closeDecryptSession");
686    Parcel data, reply;
687
688    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
689    data.writeInt32(uniqueId);
690
691    writeDecryptHandleToParcelData(decryptHandle, &data);
692
693    remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
694
695    return reply.readInt32();
696}
697
698status_t BpDrmManagerService::initializeDecryptUnit(
699            int uniqueId, DecryptHandle* decryptHandle,
700            int decryptUnitId, const DrmBuffer* headerInfo) {
701    ALOGV("initializeDecryptUnit");
702    Parcel data, reply;
703
704    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
705    data.writeInt32(uniqueId);
706
707    writeDecryptHandleToParcelData(decryptHandle, &data);
708
709    data.writeInt32(decryptUnitId);
710
711    data.writeInt32(headerInfo->length);
712    data.write(headerInfo->data, headerInfo->length);
713
714    remote()->transact(INITIALIZE_DECRYPT_UNIT, data, &reply);
715    return reply.readInt32();
716}
717
718status_t BpDrmManagerService::decrypt(
719            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
720            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
721    ALOGV("decrypt");
722    Parcel data, reply;
723
724    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
725    data.writeInt32(uniqueId);
726
727    writeDecryptHandleToParcelData(decryptHandle, &data);
728
729    data.writeInt32(decryptUnitId);
730    data.writeInt32((*decBuffer)->length);
731
732    data.writeInt32(encBuffer->length);
733    data.write(encBuffer->data, encBuffer->length);
734
735    if (NULL != IV) {
736        data.writeInt32(IV->length);
737        data.write(IV->data, IV->length);
738    }
739
740    remote()->transact(DECRYPT, data, &reply);
741
742    const status_t status = reply.readInt32();
743    ALOGV("Return value of decrypt() is %d", status);
744
745    if (status == NO_ERROR) {
746        const int size = reply.readInt32();
747        (*decBuffer)->length = size;
748        reply.read((void *)(*decBuffer)->data, size);
749    }
750
751    return status;
752}
753
754status_t BpDrmManagerService::finalizeDecryptUnit(
755            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
756    ALOGV("finalizeDecryptUnit");
757    Parcel data, reply;
758
759    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
760    data.writeInt32(uniqueId);
761
762    writeDecryptHandleToParcelData(decryptHandle, &data);
763
764    data.writeInt32(decryptUnitId);
765
766    remote()->transact(FINALIZE_DECRYPT_UNIT, data, &reply);
767    return reply.readInt32();
768}
769
770ssize_t BpDrmManagerService::pread(
771            int uniqueId, DecryptHandle* decryptHandle, void* buffer,
772            ssize_t numBytes, off64_t offset) {
773    ALOGV("read");
774    Parcel data, reply;
775    int result;
776
777    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
778    data.writeInt32(uniqueId);
779
780    writeDecryptHandleToParcelData(decryptHandle, &data);
781
782    data.writeInt32(numBytes);
783    data.writeInt64(offset);
784
785    remote()->transact(PREAD, data, &reply);
786    result = reply.readInt32();
787    if (0 < result) {
788        reply.read(buffer, result);
789    }
790    return result;
791}
792
793IMPLEMENT_META_INTERFACE(DrmManagerService, "drm.IDrmManagerService");
794
795status_t BnDrmManagerService::onTransact(
796            uint32_t code, const Parcel& data,
797            Parcel* reply, uint32_t flags) {
798    ALOGV("Entering BnDrmManagerService::onTransact with code %d", code);
799
800    switch (code) {
801    case ADD_UNIQUEID:
802    {
803        ALOGV("BnDrmManagerService::onTransact :ADD_UNIQUEID");
804        CHECK_INTERFACE(IDrmManagerService, data, reply);
805        int uniqueId = addUniqueId(data.readInt32());
806        reply->writeInt32(uniqueId);
807        return DRM_NO_ERROR;
808    }
809
810    case REMOVE_UNIQUEID:
811    {
812        ALOGV("BnDrmManagerService::onTransact :REMOVE_UNIQUEID");
813        CHECK_INTERFACE(IDrmManagerService, data, reply);
814        removeUniqueId(data.readInt32());
815        return DRM_NO_ERROR;
816    }
817
818    case ADD_CLIENT:
819    {
820        ALOGV("BnDrmManagerService::onTransact :ADD_CLIENT");
821        CHECK_INTERFACE(IDrmManagerService, data, reply);
822        addClient(data.readInt32());
823        return DRM_NO_ERROR;
824    }
825
826    case REMOVE_CLIENT:
827    {
828        ALOGV("BnDrmManagerService::onTransact :REMOVE_CLIENT");
829        CHECK_INTERFACE(IDrmManagerService, data, reply);
830        removeClient(data.readInt32());
831        return DRM_NO_ERROR;
832    }
833
834    case SET_DRM_SERVICE_LISTENER:
835    {
836        ALOGV("BnDrmManagerService::onTransact :SET_DRM_SERVICE_LISTENER");
837        CHECK_INTERFACE(IDrmManagerService, data, reply);
838
839        const int uniqueId = data.readInt32();
840        const sp<IDrmServiceListener> drmServiceListener
841            = interface_cast<IDrmServiceListener> (data.readStrongBinder());
842
843        status_t status = setDrmServiceListener(uniqueId, drmServiceListener);
844
845        reply->writeInt32(status);
846        return DRM_NO_ERROR;
847    }
848
849    case GET_CONSTRAINTS_FROM_CONTENT:
850    {
851        ALOGV("BnDrmManagerService::onTransact :GET_CONSTRAINTS_FROM_CONTENT");
852        CHECK_INTERFACE(IDrmManagerService, data, reply);
853
854        const int uniqueId = data.readInt32();
855        const String8 path = data.readString8();
856
857        DrmConstraints* drmConstraints
858            = getConstraints(uniqueId, &path, data.readInt32());
859
860        if (NULL != drmConstraints) {
861            //Filling DRM Constraints contents
862            reply->writeInt32(drmConstraints->getCount());
863
864            DrmConstraints::KeyIterator keyIt = drmConstraints->keyIterator();
865            while (keyIt.hasNext()) {
866                const String8 key = keyIt.next();
867                reply->writeString8(key);
868                const char* value = drmConstraints->getAsByteArray(&key);
869                int bufferSize = 0;
870                if (NULL != value) {
871                    bufferSize = strlen(value);
872                    reply->writeInt32(bufferSize + 1);
873                    reply->write(value, bufferSize + 1);
874                } else {
875                    reply->writeInt32(0);
876                }
877            }
878        }
879        delete drmConstraints; drmConstraints = NULL;
880        return DRM_NO_ERROR;
881    }
882
883    case GET_METADATA_FROM_CONTENT:
884    {
885        ALOGV("BnDrmManagerService::onTransact :GET_METADATA_FROM_CONTENT");
886        CHECK_INTERFACE(IDrmManagerService, data, reply);
887
888        const int uniqueId = data.readInt32();
889        const String8 path = data.readString8();
890
891        DrmMetadata* drmMetadata = getMetadata(uniqueId, &path);
892        if (NULL != drmMetadata) {
893            //Filling DRM Metadata contents
894            reply->writeInt32(drmMetadata->getCount());
895
896            DrmMetadata::KeyIterator keyIt = drmMetadata->keyIterator();
897            while (keyIt.hasNext()) {
898                const String8 key = keyIt.next();
899                reply->writeString8(key);
900                const char* value = drmMetadata->getAsByteArray(&key);
901                int bufferSize = 0;
902                if (NULL != value) {
903                    bufferSize = strlen(value);
904                    reply->writeInt32(bufferSize + 1);
905                    reply->write(value, bufferSize + 1);
906                } else {
907                    reply->writeInt32(0);
908                }
909            }
910        }
911        delete drmMetadata; drmMetadata = NULL;
912        return NO_ERROR;
913    }
914
915    case CAN_HANDLE:
916    {
917        ALOGV("BnDrmManagerService::onTransact :CAN_HANDLE");
918        CHECK_INTERFACE(IDrmManagerService, data, reply);
919
920        const int uniqueId = data.readInt32();
921        const String8 path = data.readString8();
922        const String8 mimeType = data.readString8();
923
924        bool result = canHandle(uniqueId, path, mimeType);
925
926        reply->writeInt32(result);
927        return DRM_NO_ERROR;
928    }
929
930    case PROCESS_DRM_INFO:
931    {
932        ALOGV("BnDrmManagerService::onTransact :PROCESS_DRM_INFO");
933        CHECK_INTERFACE(IDrmManagerService, data, reply);
934
935        const int uniqueId = data.readInt32();
936
937        //Filling DRM info
938        const int infoType = data.readInt32();
939        const uint32_t bufferSize = data.readInt32();
940
941        if (bufferSize > data.dataAvail()) {
942            return BAD_VALUE;
943        }
944
945        char* buffer = NULL;
946        if (0 < bufferSize) {
947            buffer = (char *)data.readInplace(bufferSize);
948        }
949        const DrmBuffer drmBuffer(buffer, bufferSize);
950        DrmInfo* drmInfo = new DrmInfo(infoType, drmBuffer, data.readString8());
951
952        const int size = data.readInt32();
953        for (int index = 0; index < size; ++index) {
954            const String8 key(data.readString8());
955            const String8 value(data.readString8());
956            drmInfo->put(key, (value == String8("NULL")) ? String8("") : value);
957        }
958
959        DrmInfoStatus* drmInfoStatus = processDrmInfo(uniqueId, drmInfo);
960
961        if (NULL != drmInfoStatus) {
962            //Filling DRM Info Status contents
963            reply->writeInt32(drmInfoStatus->statusCode);
964            reply->writeInt32(drmInfoStatus->infoType);
965            reply->writeString8(drmInfoStatus->mimeType);
966
967            if (NULL != drmInfoStatus->drmBuffer) {
968                const DrmBuffer* drmBuffer = drmInfoStatus->drmBuffer;
969                const int bufferSize = drmBuffer->length;
970                reply->writeInt32(bufferSize);
971                if (0 < bufferSize) {
972                    reply->write(drmBuffer->data, bufferSize);
973                }
974                delete [] drmBuffer->data;
975                delete drmBuffer; drmBuffer = NULL;
976            }
977        }
978        delete drmInfo; drmInfo = NULL;
979        delete drmInfoStatus; drmInfoStatus = NULL;
980        return DRM_NO_ERROR;
981    }
982
983    case ACQUIRE_DRM_INFO:
984    {
985        ALOGV("BnDrmManagerService::onTransact :ACQUIRE_DRM_INFO");
986        CHECK_INTERFACE(IDrmManagerService, data, reply);
987
988        const int uniqueId = data.readInt32();
989
990        //Filling DRM info Request
991        const int infoType = data.readInt32();
992        const String8 mimeType = data.readString8();
993        DrmInfoRequest* drmInfoRequest = new DrmInfoRequest(infoType, mimeType);
994
995        const int size = data.readInt32();
996        for (int index = 0; index < size; ++index) {
997            if (!data.dataAvail()) {
998                break;
999            }
1000            const String8 key(data.readString8());
1001            if (key == String8("FileDescriptorKey")) {
1002                char buffer[16];
1003                int fd = data.readFileDescriptor();
1004                sprintf(buffer, "%lu", (unsigned long)fd);
1005                drmInfoRequest->put(key, String8(buffer));
1006            } else {
1007                const String8 value(data.readString8());
1008                drmInfoRequest->put(key, (value == String8("NULL")) ? String8("") : value);
1009            }
1010        }
1011
1012        DrmInfo* drmInfo = acquireDrmInfo(uniqueId, drmInfoRequest);
1013
1014        if (NULL != drmInfo) {
1015            //Filling DRM Info
1016            const DrmBuffer drmBuffer = drmInfo->getData();
1017            reply->writeInt32(drmInfo->getInfoType());
1018
1019            const int bufferSize = drmBuffer.length;
1020            reply->writeInt32(bufferSize);
1021            if (0 < bufferSize) {
1022                reply->write(drmBuffer.data, bufferSize);
1023            }
1024            reply->writeString8(drmInfo->getMimeType());
1025            reply->writeInt32(drmInfo->getCount());
1026
1027            DrmInfo::KeyIterator keyIt = drmInfo->keyIterator();
1028            while (keyIt.hasNext()) {
1029                const String8 key = keyIt.next();
1030                reply->writeString8(key);
1031                const String8 value = drmInfo->get(key);
1032                reply->writeString8((value == String8("")) ? String8("NULL") : value);
1033            }
1034            delete [] drmBuffer.data;
1035        }
1036        delete drmInfoRequest; drmInfoRequest = NULL;
1037        delete drmInfo; drmInfo = NULL;
1038        return DRM_NO_ERROR;
1039    }
1040
1041    case SAVE_RIGHTS:
1042    {
1043        ALOGV("BnDrmManagerService::onTransact :SAVE_RIGHTS");
1044        CHECK_INTERFACE(IDrmManagerService, data, reply);
1045
1046        const int uniqueId = data.readInt32();
1047
1048        //Filling DRM Rights
1049        const uint32_t bufferSize = data.readInt32();
1050        if (bufferSize > data.dataAvail()) {
1051            reply->writeInt32(BAD_VALUE);
1052            return DRM_NO_ERROR;
1053        }
1054
1055        const DrmBuffer drmBuffer((char *)data.readInplace(bufferSize), bufferSize);
1056
1057        const String8 mimeType(data.readString8());
1058        const String8 accountId(data.readString8());
1059        const String8 subscriptionId(data.readString8());
1060        const String8 rightsPath(data.readString8());
1061        const String8 contentPath(data.readString8());
1062
1063        DrmRights drmRights(drmBuffer,
1064                            ((mimeType == String8("NULL")) ? String8("") : mimeType),
1065                            ((accountId == String8("NULL")) ? String8("") : accountId),
1066                            ((subscriptionId == String8("NULL")) ? String8("") : subscriptionId));
1067
1068        const status_t status = saveRights(uniqueId, drmRights,
1069                            ((rightsPath == String8("NULL")) ? String8("") : rightsPath),
1070                            ((contentPath == String8("NULL")) ? String8("") : contentPath));
1071
1072        reply->writeInt32(status);
1073        return DRM_NO_ERROR;
1074    }
1075
1076    case GET_ORIGINAL_MIMETYPE:
1077    {
1078        ALOGV("BnDrmManagerService::onTransact :GET_ORIGINAL_MIMETYPE");
1079        CHECK_INTERFACE(IDrmManagerService, data, reply);
1080
1081        const int uniqueId = data.readInt32();
1082        const String8 path = data.readString8();
1083        const int32_t isFdValid = data.readInt32();
1084        int fd = -1;
1085        if (isFdValid) {
1086            fd = data.readFileDescriptor();
1087        }
1088        const String8 originalMimeType = getOriginalMimeType(uniqueId, path, fd);
1089
1090        reply->writeString8(originalMimeType);
1091        return DRM_NO_ERROR;
1092    }
1093
1094    case GET_DRM_OBJECT_TYPE:
1095    {
1096        ALOGV("BnDrmManagerService::onTransact :GET_DRM_OBJECT_TYPE");
1097        CHECK_INTERFACE(IDrmManagerService, data, reply);
1098
1099        const int uniqueId = data.readInt32();
1100        const String8 path = data.readString8();
1101        const String8 mimeType = data.readString8();
1102        const int drmObjectType = getDrmObjectType(uniqueId, path, mimeType);
1103
1104        reply->writeInt32(drmObjectType);
1105        return DRM_NO_ERROR;
1106    }
1107
1108    case CHECK_RIGHTS_STATUS:
1109    {
1110        ALOGV("BnDrmManagerService::onTransact :CHECK_RIGHTS_STATUS");
1111        CHECK_INTERFACE(IDrmManagerService, data, reply);
1112
1113        const int uniqueId = data.readInt32();
1114        const String8 path = data.readString8();
1115        const int action = data.readInt32();
1116        const int result = checkRightsStatus(uniqueId, path, action);
1117
1118        reply->writeInt32(result);
1119        return DRM_NO_ERROR;
1120    }
1121
1122    case CONSUME_RIGHTS:
1123    {
1124        ALOGV("BnDrmManagerService::onTransact :CONSUME_RIGHTS");
1125        CHECK_INTERFACE(IDrmManagerService, data, reply);
1126
1127        const int uniqueId = data.readInt32();
1128
1129        DecryptHandle handle;
1130        readDecryptHandleFromParcelData(&handle, data);
1131
1132        const int action = data.readInt32();
1133        const bool reserve = static_cast<bool>(data.readInt32());
1134        const status_t status
1135            = consumeRights(uniqueId, &handle, action, reserve);
1136        reply->writeInt32(status);
1137
1138        clearDecryptHandle(&handle);
1139        return DRM_NO_ERROR;
1140    }
1141
1142    case SET_PLAYBACK_STATUS:
1143    {
1144        ALOGV("BnDrmManagerService::onTransact :SET_PLAYBACK_STATUS");
1145        CHECK_INTERFACE(IDrmManagerService, data, reply);
1146
1147        const int uniqueId = data.readInt32();
1148
1149        DecryptHandle handle;
1150        readDecryptHandleFromParcelData(&handle, data);
1151
1152        const int playbackStatus = data.readInt32();
1153        const int64_t position = data.readInt64();
1154        const status_t status
1155            = setPlaybackStatus(uniqueId, &handle, playbackStatus, position);
1156        reply->writeInt32(status);
1157
1158        clearDecryptHandle(&handle);
1159        return DRM_NO_ERROR;
1160    }
1161
1162    case VALIDATE_ACTION:
1163    {
1164        ALOGV("BnDrmManagerService::onTransact :VALIDATE_ACTION");
1165        CHECK_INTERFACE(IDrmManagerService, data, reply);
1166
1167        const int uniqueId = data.readInt32();
1168        const String8 path = data.readString8();
1169        const int action = data.readInt32();
1170        const int outputType = data.readInt32();
1171        const int configuration = data.readInt32();
1172        bool result = validateAction(uniqueId, path, action,
1173                ActionDescription(outputType, configuration));
1174
1175        reply->writeInt32(result);
1176        return DRM_NO_ERROR;
1177    }
1178
1179    case REMOVE_RIGHTS:
1180    {
1181        ALOGV("BnDrmManagerService::onTransact :REMOVE_RIGHTS");
1182        CHECK_INTERFACE(IDrmManagerService, data, reply);
1183
1184        int uniqueId = data.readInt32();
1185        String8 path = data.readString8();
1186        const status_t status = removeRights(uniqueId, path);
1187        reply->writeInt32(status);
1188
1189        return DRM_NO_ERROR;
1190    }
1191
1192    case REMOVE_ALL_RIGHTS:
1193    {
1194        ALOGV("BnDrmManagerService::onTransact :REMOVE_ALL_RIGHTS");
1195        CHECK_INTERFACE(IDrmManagerService, data, reply);
1196
1197        const status_t status = removeAllRights(data.readInt32());
1198        reply->writeInt32(status);
1199
1200        return DRM_NO_ERROR;
1201    }
1202
1203    case OPEN_CONVERT_SESSION:
1204    {
1205        ALOGV("BnDrmManagerService::onTransact :OPEN_CONVERT_SESSION");
1206        CHECK_INTERFACE(IDrmManagerService, data, reply);
1207
1208        const int uniqueId = data.readInt32();
1209        const String8 mimeType = data.readString8();
1210        const int convertId = openConvertSession(uniqueId, mimeType);
1211
1212        reply->writeInt32(convertId);
1213        return DRM_NO_ERROR;
1214    }
1215
1216    case CONVERT_DATA:
1217    {
1218        ALOGV("BnDrmManagerService::onTransact :CONVERT_DATA");
1219        CHECK_INTERFACE(IDrmManagerService, data, reply);
1220
1221        const int uniqueId = data.readInt32();
1222        const int convertId = data.readInt32();
1223
1224        //Filling input data
1225        const uint32_t bufferSize = data.readInt32();
1226        if (bufferSize > data.dataAvail()) {
1227            return BAD_VALUE;
1228        }
1229        DrmBuffer* inputData = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
1230
1231        DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData);
1232
1233        if (NULL != drmConvertedStatus) {
1234            //Filling Drm Converted Ststus
1235            reply->writeInt32(drmConvertedStatus->statusCode);
1236            reply->writeInt64(drmConvertedStatus->offset);
1237
1238            if (NULL != drmConvertedStatus->convertedData) {
1239                const DrmBuffer* convertedData = drmConvertedStatus->convertedData;
1240                const int bufferSize = convertedData->length;
1241                reply->writeInt32(bufferSize);
1242                if (0 < bufferSize) {
1243                    reply->write(convertedData->data, bufferSize);
1244                }
1245                delete [] convertedData->data;
1246                delete convertedData; convertedData = NULL;
1247            }
1248        }
1249        delete inputData; inputData = NULL;
1250        delete drmConvertedStatus; drmConvertedStatus = NULL;
1251        return DRM_NO_ERROR;
1252    }
1253
1254    case CLOSE_CONVERT_SESSION:
1255    {
1256        ALOGV("BnDrmManagerService::onTransact :CLOSE_CONVERT_SESSION");
1257        CHECK_INTERFACE(IDrmManagerService, data, reply);
1258
1259        const int uniqueId = data.readInt32();
1260        const int convertId = data.readInt32();
1261        DrmConvertedStatus* drmConvertedStatus
1262            = closeConvertSession(uniqueId, convertId);
1263
1264        if (NULL != drmConvertedStatus) {
1265            //Filling Drm Converted Ststus
1266            reply->writeInt32(drmConvertedStatus->statusCode);
1267            reply->writeInt64(drmConvertedStatus->offset);
1268
1269            if (NULL != drmConvertedStatus->convertedData) {
1270                const DrmBuffer* convertedData = drmConvertedStatus->convertedData;
1271                const int bufferSize = convertedData->length;
1272                reply->writeInt32(bufferSize);
1273                if (0 < bufferSize) {
1274                    reply->write(convertedData->data, bufferSize);
1275                }
1276                delete [] convertedData->data;
1277                delete convertedData; convertedData = NULL;
1278            }
1279        }
1280        delete drmConvertedStatus; drmConvertedStatus = NULL;
1281        return DRM_NO_ERROR;
1282    }
1283
1284    case GET_ALL_SUPPORT_INFO:
1285    {
1286        ALOGV("BnDrmManagerService::onTransact :GET_ALL_SUPPORT_INFO");
1287        CHECK_INTERFACE(IDrmManagerService, data, reply);
1288
1289        const int uniqueId = data.readInt32();
1290        int length = 0;
1291        DrmSupportInfo* drmSupportInfoArray = NULL;
1292
1293        status_t status = getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
1294
1295        reply->writeInt32(length);
1296        for (int i = 0; i < length; ++i) {
1297            DrmSupportInfo drmSupportInfo = drmSupportInfoArray[i];
1298
1299            reply->writeInt32(drmSupportInfo.getFileSuffixCount());
1300            DrmSupportInfo::FileSuffixIterator fileSuffixIt
1301                = drmSupportInfo.getFileSuffixIterator();
1302            while (fileSuffixIt.hasNext()) {
1303                reply->writeString8(fileSuffixIt.next());
1304            }
1305
1306            reply->writeInt32(drmSupportInfo.getMimeTypeCount());
1307            DrmSupportInfo::MimeTypeIterator mimeTypeIt = drmSupportInfo.getMimeTypeIterator();
1308            while (mimeTypeIt.hasNext()) {
1309                reply->writeString8(mimeTypeIt.next());
1310            }
1311            reply->writeString8(drmSupportInfo.getDescription());
1312        }
1313        delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
1314        reply->writeInt32(status);
1315        return DRM_NO_ERROR;
1316    }
1317
1318    case OPEN_DECRYPT_SESSION:
1319    {
1320        ALOGV("BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION");
1321        CHECK_INTERFACE(IDrmManagerService, data, reply);
1322
1323        const int uniqueId = data.readInt32();
1324        const int fd = data.readFileDescriptor();
1325
1326        const off64_t offset = data.readInt64();
1327        const off64_t length = data.readInt64();
1328        const String8 mime = data.readString8();
1329
1330        DecryptHandle* handle
1331            = openDecryptSession(uniqueId, fd, offset, length, mime.string());
1332
1333        if (NULL != handle) {
1334            writeDecryptHandleToParcelData(handle, reply);
1335            clearDecryptHandle(handle);
1336            delete handle; handle = NULL;
1337        }
1338        return DRM_NO_ERROR;
1339    }
1340
1341    case OPEN_DECRYPT_SESSION_FROM_URI:
1342    {
1343        ALOGV("BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FROM_URI");
1344        CHECK_INTERFACE(IDrmManagerService, data, reply);
1345
1346        const int uniqueId = data.readInt32();
1347        const String8 uri = data.readString8();
1348        const String8 mime = data.readString8();
1349
1350        DecryptHandle* handle = openDecryptSession(uniqueId, uri.string(), mime.string());
1351
1352        if (NULL != handle) {
1353            writeDecryptHandleToParcelData(handle, reply);
1354
1355            clearDecryptHandle(handle);
1356            delete handle; handle = NULL;
1357        } else {
1358            ALOGV("NULL decryptHandle is returned");
1359        }
1360        return DRM_NO_ERROR;
1361    }
1362
1363    case OPEN_DECRYPT_SESSION_FOR_STREAMING:
1364    {
1365        ALOGV("BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FOR_STREAMING");
1366        CHECK_INTERFACE(IDrmManagerService, data, reply);
1367
1368        const int uniqueId = data.readInt32();
1369        const int bufferSize = data.readInt32();
1370        DrmBuffer buf((bufferSize > 0) ? (char *)data.readInplace(bufferSize) : NULL,
1371                bufferSize);
1372        const String8 mimeType(data.readString8());
1373
1374        DecryptHandle* handle = openDecryptSession(uniqueId, buf, mimeType);
1375
1376        if (handle != NULL) {
1377            writeDecryptHandleToParcelData(handle, reply);
1378            clearDecryptHandle(handle);
1379            delete handle;
1380            handle = NULL;
1381        } else {
1382            ALOGV("NULL decryptHandle is returned");
1383        }
1384        return DRM_NO_ERROR;
1385    }
1386
1387    case CLOSE_DECRYPT_SESSION:
1388    {
1389        ALOGV("BnDrmManagerService::onTransact :CLOSE_DECRYPT_SESSION");
1390        CHECK_INTERFACE(IDrmManagerService, data, reply);
1391
1392        const int uniqueId = data.readInt32();
1393
1394        DecryptHandle* handle = new DecryptHandle();
1395        readDecryptHandleFromParcelData(handle, data);
1396
1397        const status_t status = closeDecryptSession(uniqueId, handle);
1398        reply->writeInt32(status);
1399        return DRM_NO_ERROR;
1400    }
1401
1402    case INITIALIZE_DECRYPT_UNIT:
1403    {
1404        ALOGV("BnDrmManagerService::onTransact :INITIALIZE_DECRYPT_UNIT");
1405        CHECK_INTERFACE(IDrmManagerService, data, reply);
1406
1407        const int uniqueId = data.readInt32();
1408
1409        DecryptHandle handle;
1410        readDecryptHandleFromParcelData(&handle, data);
1411
1412        const int decryptUnitId = data.readInt32();
1413
1414        //Filling Header info
1415        const uint32_t bufferSize = data.readInt32();
1416        if (bufferSize > data.dataAvail()) {
1417            reply->writeInt32(BAD_VALUE);
1418            clearDecryptHandle(&handle);
1419            return DRM_NO_ERROR;
1420        }
1421        DrmBuffer* headerInfo = NULL;
1422        headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
1423
1424        const status_t status
1425            = initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
1426        reply->writeInt32(status);
1427
1428        clearDecryptHandle(&handle);
1429        delete headerInfo; headerInfo = NULL;
1430        return DRM_NO_ERROR;
1431    }
1432
1433    case DECRYPT:
1434    {
1435        ALOGV("BnDrmManagerService::onTransact :DECRYPT");
1436        CHECK_INTERFACE(IDrmManagerService, data, reply);
1437
1438        const int uniqueId = data.readInt32();
1439
1440        DecryptHandle handle;
1441        readDecryptHandleFromParcelData(&handle, data);
1442
1443        const int decryptUnitId = data.readInt32();
1444        const uint32_t decBufferSize = data.readInt32();
1445        const uint32_t encBufferSize = data.readInt32();
1446
1447        if (encBufferSize > data.dataAvail() ||
1448            decBufferSize > MAX_BINDER_TRANSACTION_SIZE) {
1449            reply->writeInt32(BAD_VALUE);
1450            reply->writeInt32(0);
1451            clearDecryptHandle(&handle);
1452            return DRM_NO_ERROR;
1453        }
1454
1455        DrmBuffer* encBuffer
1456            = new DrmBuffer((char *)data.readInplace(encBufferSize), encBufferSize);
1457
1458        char* buffer = NULL;
1459        buffer = new char[decBufferSize];
1460        DrmBuffer* decBuffer = new DrmBuffer(buffer, decBufferSize);
1461
1462        DrmBuffer* IV = NULL;
1463        if (0 != data.dataAvail()) {
1464            const uint32_t ivBufferlength = data.readInt32();
1465            if (ivBufferlength <= data.dataAvail()) {
1466                IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength);
1467            }
1468        }
1469
1470        const status_t status
1471            = decrypt(uniqueId, &handle, decryptUnitId, encBuffer, &decBuffer, IV);
1472
1473        reply->writeInt32(status);
1474
1475        if (status == NO_ERROR) {
1476            const int size = decBuffer->length;
1477            reply->writeInt32(size);
1478            reply->write(decBuffer->data, size);
1479        }
1480
1481        clearDecryptHandle(&handle);
1482        delete encBuffer; encBuffer = NULL;
1483        delete decBuffer; decBuffer = NULL;
1484        delete [] buffer; buffer = NULL;
1485        delete IV; IV = NULL;
1486        return DRM_NO_ERROR;
1487    }
1488
1489    case FINALIZE_DECRYPT_UNIT:
1490    {
1491        ALOGV("BnDrmManagerService::onTransact :FINALIZE_DECRYPT_UNIT");
1492        CHECK_INTERFACE(IDrmManagerService, data, reply);
1493
1494        const int uniqueId = data.readInt32();
1495
1496        DecryptHandle handle;
1497        readDecryptHandleFromParcelData(&handle, data);
1498
1499        const status_t status = finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
1500        reply->writeInt32(status);
1501
1502        clearDecryptHandle(&handle);
1503        return DRM_NO_ERROR;
1504    }
1505
1506    case PREAD:
1507    {
1508        ALOGV("BnDrmManagerService::onTransact :READ");
1509        CHECK_INTERFACE(IDrmManagerService, data, reply);
1510
1511        const int uniqueId = data.readInt32();
1512
1513        DecryptHandle handle;
1514        readDecryptHandleFromParcelData(&handle, data);
1515
1516        const uint32_t numBytes = data.readInt32();
1517        if (numBytes > MAX_BINDER_TRANSACTION_SIZE) {
1518            reply->writeInt32(BAD_VALUE);
1519            return DRM_NO_ERROR;
1520        }
1521        char* buffer = new char[numBytes];
1522
1523        const off64_t offset = data.readInt64();
1524
1525        ssize_t result = pread(uniqueId, &handle, buffer, numBytes, offset);
1526        reply->writeInt32(result);
1527        if (0 < result) {
1528            reply->write(buffer, result);
1529        }
1530
1531        clearDecryptHandle(&handle);
1532        delete [] buffer, buffer = NULL;
1533        return DRM_NO_ERROR;
1534    }
1535
1536    default:
1537        return BBinder::onTransact(code, data, reply, flags);
1538    }
1539}
1540