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