1/*
2 * Copyright (C) 2013 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 "IDrm"
19#include <utils/Log.h>
20
21#include <binder/Parcel.h>
22#include <media/stagefright/MediaErrors.h>
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/foundation/AString.h>
25#include <mediadrm/IDrm.h>
26
27namespace android {
28
29enum {
30    INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
31    IS_CRYPTO_SUPPORTED,
32    CREATE_PLUGIN,
33    DESTROY_PLUGIN,
34    OPEN_SESSION,
35    CLOSE_SESSION,
36    GET_KEY_REQUEST,
37    PROVIDE_KEY_RESPONSE,
38    REMOVE_KEYS,
39    RESTORE_KEYS,
40    QUERY_KEY_STATUS,
41    GET_PROVISION_REQUEST,
42    PROVIDE_PROVISION_RESPONSE,
43    GET_SECURE_STOPS,
44    RELEASE_SECURE_STOPS,
45    GET_PROPERTY_STRING,
46    GET_PROPERTY_BYTE_ARRAY,
47    SET_PROPERTY_STRING,
48    SET_PROPERTY_BYTE_ARRAY,
49    GET_METRICS,
50    SET_CIPHER_ALGORITHM,
51    SET_MAC_ALGORITHM,
52    ENCRYPT,
53    DECRYPT,
54    SIGN,
55    SIGN_RSA,
56    VERIFY,
57    SET_LISTENER,
58    GET_SECURE_STOP,
59    REMOVE_ALL_SECURE_STOPS,
60    GET_HDCP_LEVELS,
61    GET_NUMBER_OF_SESSIONS,
62    GET_SECURITY_LEVEL,
63    REMOVE_SECURE_STOP,
64    GET_SECURE_STOP_IDS
65};
66
67struct BpDrm : public BpInterface<IDrm> {
68    explicit BpDrm(const sp<IBinder> &impl)
69        : BpInterface<IDrm>(impl) {
70    }
71
72    virtual status_t initCheck() const {
73        Parcel data, reply;
74        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
75        status_t status = remote()->transact(INIT_CHECK, data, &reply);
76        if (status != OK) {
77            return status;
78        }
79
80        return reply.readInt32();
81    }
82
83    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
84        Parcel data, reply;
85        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
86        data.write(uuid, 16);
87        data.writeString8(mimeType);
88        status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
89        if (status != OK) {
90            ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
91            return false;
92        }
93
94        return reply.readInt32() != 0;
95    }
96
97    virtual status_t createPlugin(const uint8_t uuid[16],
98                                  const String8& appPackageName) {
99        Parcel data, reply;
100        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
101        data.write(uuid, 16);
102        data.writeString8(appPackageName);
103        status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
104        if (status != OK) {
105            ALOGE("createPlugin: binder call failed: %d", status);
106            return status;
107        }
108
109        return reply.readInt32();
110    }
111
112    virtual status_t destroyPlugin() {
113        Parcel data, reply;
114        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
115        status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
116        if (status != OK) {
117            return status;
118        }
119
120        return reply.readInt32();
121    }
122
123    virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
124            Vector<uint8_t> &sessionId) {
125        Parcel data, reply;
126        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
127        data.writeInt32(securityLevel);
128
129        status_t status = remote()->transact(OPEN_SESSION, data, &reply);
130        if (status != OK) {
131            return status;
132        }
133        readVector(reply, sessionId);
134
135        return reply.readInt32();
136    }
137
138    virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
139        Parcel data, reply;
140        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
141
142        writeVector(data, sessionId);
143        status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
144        if (status != OK) {
145            return status;
146        }
147
148        return reply.readInt32();
149    }
150
151    virtual status_t
152        getKeyRequest(Vector<uint8_t> const &sessionId,
153                      Vector<uint8_t> const &initData,
154                      String8 const &mimeType, DrmPlugin::KeyType keyType,
155                      KeyedVector<String8, String8> const &optionalParameters,
156                      Vector<uint8_t> &request, String8 &defaultUrl,
157                      DrmPlugin::KeyRequestType *keyRequestType) {
158        Parcel data, reply;
159        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
160
161        writeVector(data, sessionId);
162        writeVector(data, initData);
163        data.writeString8(mimeType);
164        data.writeInt32((uint32_t)keyType);
165
166        data.writeInt32(optionalParameters.size());
167        for (size_t i = 0; i < optionalParameters.size(); ++i) {
168            data.writeString8(optionalParameters.keyAt(i));
169            data.writeString8(optionalParameters.valueAt(i));
170        }
171
172        status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
173        if (status != OK) {
174            return status;
175        }
176
177        readVector(reply, request);
178        defaultUrl = reply.readString8();
179        *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
180
181        return reply.readInt32();
182    }
183
184    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
185                                        Vector<uint8_t> const &response,
186                                        Vector<uint8_t> &keySetId) {
187        Parcel data, reply;
188        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
189        writeVector(data, sessionId);
190        writeVector(data, response);
191
192        status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
193        if (status != OK) {
194            return status;
195        }
196
197        readVector(reply, keySetId);
198
199        return reply.readInt32();
200    }
201
202    virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
203        Parcel data, reply;
204        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
205
206        writeVector(data, keySetId);
207        status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
208        if (status != OK) {
209            return status;
210        }
211
212        return reply.readInt32();
213    }
214
215    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
216                                 Vector<uint8_t> const &keySetId) {
217        Parcel data, reply;
218        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
219
220        writeVector(data, sessionId);
221        writeVector(data, keySetId);
222        status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
223        if (status != OK) {
224            return status;
225        }
226
227        return reply.readInt32();
228    }
229
230    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
231                                        KeyedVector<String8, String8> &infoMap) const {
232        Parcel data, reply;
233        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
234
235        writeVector(data, sessionId);
236        status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
237        if (status != OK) {
238            return status;
239        }
240
241        infoMap.clear();
242        size_t count = reply.readInt32();
243        for (size_t i = 0; i < count; i++) {
244            String8 key = reply.readString8();
245            String8 value = reply.readString8();
246            infoMap.add(key, value);
247        }
248        return reply.readInt32();
249    }
250
251    virtual status_t getProvisionRequest(String8 const &certType,
252                                         String8 const &certAuthority,
253                                         Vector<uint8_t> &request,
254                                         String8 &defaultUrl) {
255        Parcel data, reply;
256        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
257
258        data.writeString8(certType);
259        data.writeString8(certAuthority);
260        status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
261        if (status != OK) {
262            return status;
263        }
264
265        readVector(reply, request);
266        defaultUrl = reply.readString8();
267
268        return reply.readInt32();
269    }
270
271    virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
272                                              Vector<uint8_t> &certificate,
273                                              Vector<uint8_t> &wrappedKey) {
274        Parcel data, reply;
275        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
276
277        writeVector(data, response);
278        status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
279        if (status != OK) {
280            return status;
281        }
282
283        readVector(reply, certificate);
284        readVector(reply, wrappedKey);
285
286        return reply.readInt32();
287    }
288
289    virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
290        Parcel data, reply;
291        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
292
293        status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
294        if (status != OK) {
295            return status;
296        }
297
298        secureStops.clear();
299        uint32_t count = reply.readInt32();
300        for (size_t i = 0; i < count; i++) {
301            Vector<uint8_t> secureStop;
302            readVector(reply, secureStop);
303            secureStops.push_back(secureStop);
304        }
305        return reply.readInt32();
306    }
307
308    virtual status_t getSecureStopIds(List<Vector<uint8_t> > &secureStopIds) {
309        Parcel data, reply;
310        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
311
312        status_t status = remote()->transact(GET_SECURE_STOP_IDS, data, &reply);
313        if (status != OK) {
314            return status;
315        }
316
317        secureStopIds.clear();
318        uint32_t count = reply.readInt32();
319        for (size_t i = 0; i < count; i++) {
320            Vector<uint8_t> secureStopId;
321            readVector(reply, secureStopId);
322            secureStopIds.push_back(secureStopId);
323        }
324        return reply.readInt32();
325    }
326
327    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
328        Parcel data, reply;
329        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
330
331        writeVector(data, ssid);
332        status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
333        if (status != OK) {
334            return status;
335        }
336
337        readVector(reply, secureStop);
338        return reply.readInt32();
339    }
340
341    virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
342        Parcel data, reply;
343        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
344
345        writeVector(data, ssRelease);
346        status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
347        if (status != OK) {
348            return status;
349        }
350
351        return reply.readInt32();
352    }
353
354    virtual status_t removeSecureStop(Vector<uint8_t> const &ssid) {
355        Parcel data, reply;
356        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
357
358        writeVector(data, ssid);
359        status_t status = remote()->transact(REMOVE_SECURE_STOP, data, &reply);
360        if (status != OK) {
361            return status;
362        }
363
364        return reply.readInt32();
365    }
366
367    virtual status_t removeAllSecureStops() {
368        Parcel data, reply;
369        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
370
371        status_t status = remote()->transact(REMOVE_ALL_SECURE_STOPS, data, &reply);
372        if (status != OK) {
373            return status;
374        }
375
376        return reply.readInt32();
377    }
378
379    virtual status_t getPropertyString(String8 const &name, String8 &value) const {
380        Parcel data, reply;
381        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
382
383        data.writeString8(name);
384        status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
385        if (status != OK) {
386            return status;
387        }
388
389        value = reply.readString8();
390        return reply.readInt32();
391    }
392
393    virtual status_t getHdcpLevels(DrmPlugin::HdcpLevel *connected,
394            DrmPlugin::HdcpLevel *max) const {
395        Parcel data, reply;
396
397        if (connected == NULL || max == NULL) {
398            return BAD_VALUE;
399        }
400
401        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
402
403        status_t status = remote()->transact(GET_HDCP_LEVELS, data, &reply);
404        if (status != OK) {
405            return status;
406        }
407
408        *connected = static_cast<DrmPlugin::HdcpLevel>(reply.readInt32());
409        *max = static_cast<DrmPlugin::HdcpLevel>(reply.readInt32());
410        return reply.readInt32();
411    }
412
413    virtual status_t getNumberOfSessions(uint32_t *open, uint32_t *max) const {
414        Parcel data, reply;
415
416        if (open == NULL || max == NULL) {
417            return BAD_VALUE;
418        }
419
420        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
421
422        status_t status = remote()->transact(GET_NUMBER_OF_SESSIONS, data, &reply);
423        if (status != OK) {
424            return status;
425        }
426
427        *open = reply.readInt32();
428        *max = reply.readInt32();
429        return reply.readInt32();
430    }
431
432    virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
433            DrmPlugin::SecurityLevel *level) const {
434        Parcel data, reply;
435
436        if (level == NULL) {
437            return BAD_VALUE;
438        }
439
440        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
441
442        writeVector(data, sessionId);
443        status_t status = remote()->transact(GET_SECURITY_LEVEL, data, &reply);
444        if (status != OK) {
445            return status;
446        }
447
448        *level = static_cast<DrmPlugin::SecurityLevel>(reply.readInt32());
449        return reply.readInt32();
450    }
451
452    virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
453        Parcel data, reply;
454        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
455
456        data.writeString8(name);
457        status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
458        if (status != OK) {
459            return status;
460        }
461
462        readVector(reply, value);
463        return reply.readInt32();
464    }
465
466    virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
467        Parcel data, reply;
468        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
469
470        data.writeString8(name);
471        data.writeString8(value);
472        status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
473        if (status != OK) {
474            return status;
475        }
476
477        return reply.readInt32();
478    }
479
480    virtual status_t setPropertyByteArray(String8 const &name,
481                                          Vector<uint8_t> const &value) const {
482        Parcel data, reply;
483        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
484
485        data.writeString8(name);
486        writeVector(data, value);
487        status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
488        if (status != OK) {
489            return status;
490        }
491
492        return reply.readInt32();
493    }
494
495    virtual status_t getMetrics(os::PersistableBundle *metrics) {
496        if (metrics == NULL) {
497            return BAD_VALUE;
498        }
499        Parcel data, reply;
500        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
501
502        status_t status = remote()->transact(GET_METRICS, data, &reply);
503        if (status != OK) {
504            return status;
505        }
506        // The reply data is ordered as
507        // 1) 32 bit integer reply followed by
508        // 2) Serialized PersistableBundle containing metrics.
509        status_t reply_status;
510        if (reply.readInt32(&reply_status) != OK
511           || reply_status != OK) {
512          ALOGE("Failed to read getMetrics response code from parcel. %d",
513                reply_status);
514          return reply_status;
515        }
516
517        status = metrics->readFromParcel(&reply);
518        if (status != OK) {
519            ALOGE("Failed to read metrics from parcel. %d", status);
520            return status;
521        }
522        return reply_status;
523    }
524
525    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
526                                        String8 const &algorithm) {
527        Parcel data, reply;
528        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
529
530        writeVector(data, sessionId);
531        data.writeString8(algorithm);
532        status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
533        if (status != OK) {
534            return status;
535        }
536        return reply.readInt32();
537    }
538
539    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
540                                     String8 const &algorithm) {
541        Parcel data, reply;
542        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
543
544        writeVector(data, sessionId);
545        data.writeString8(algorithm);
546        status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
547        if (status != OK) {
548            return status;
549        }
550        return reply.readInt32();
551    }
552
553    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
554                             Vector<uint8_t> const &keyId,
555                             Vector<uint8_t> const &input,
556                             Vector<uint8_t> const &iv,
557                             Vector<uint8_t> &output) {
558        Parcel data, reply;
559        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
560
561        writeVector(data, sessionId);
562        writeVector(data, keyId);
563        writeVector(data, input);
564        writeVector(data, iv);
565
566        status_t status = remote()->transact(ENCRYPT, data, &reply);
567        if (status != OK) {
568            return status;
569        }
570        readVector(reply, output);
571
572        return reply.readInt32();
573    }
574
575    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
576                             Vector<uint8_t> const &keyId,
577                             Vector<uint8_t> const &input,
578                             Vector<uint8_t> const &iv,
579                             Vector<uint8_t> &output) {
580        Parcel data, reply;
581        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
582
583        writeVector(data, sessionId);
584        writeVector(data, keyId);
585        writeVector(data, input);
586        writeVector(data, iv);
587
588        status_t status = remote()->transact(DECRYPT, data, &reply);
589        if (status != OK) {
590            return status;
591        }
592        readVector(reply, output);
593
594        return reply.readInt32();
595    }
596
597    virtual status_t sign(Vector<uint8_t> const &sessionId,
598                          Vector<uint8_t> const &keyId,
599                          Vector<uint8_t> const &message,
600                          Vector<uint8_t> &signature) {
601        Parcel data, reply;
602        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
603
604        writeVector(data, sessionId);
605        writeVector(data, keyId);
606        writeVector(data, message);
607
608        status_t status = remote()->transact(SIGN, data, &reply);
609        if (status != OK) {
610            return status;
611        }
612        readVector(reply, signature);
613
614        return reply.readInt32();
615    }
616
617    virtual status_t verify(Vector<uint8_t> const &sessionId,
618                            Vector<uint8_t> const &keyId,
619                            Vector<uint8_t> const &message,
620                            Vector<uint8_t> const &signature,
621                            bool &match) {
622        Parcel data, reply;
623        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
624
625        writeVector(data, sessionId);
626        writeVector(data, keyId);
627        writeVector(data, message);
628        writeVector(data, signature);
629
630        status_t status = remote()->transact(VERIFY, data, &reply);
631        if (status != OK) {
632            return status;
633        }
634        match = (bool)reply.readInt32();
635        return reply.readInt32();
636    }
637
638    virtual status_t signRSA(Vector<uint8_t> const &sessionId,
639                             String8 const &algorithm,
640                             Vector<uint8_t> const &message,
641                             Vector<uint8_t> const &wrappedKey,
642                             Vector<uint8_t> &signature) {
643        Parcel data, reply;
644        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
645
646        writeVector(data, sessionId);
647        data.writeString8(algorithm);
648        writeVector(data, message);
649        writeVector(data, wrappedKey);
650
651        status_t status = remote()->transact(SIGN_RSA, data, &reply);
652        if (status != OK) {
653            return status;
654        }
655        readVector(reply, signature);
656
657        return reply.readInt32();
658    }
659
660    virtual status_t setListener(const sp<IDrmClient>& listener) {
661        Parcel data, reply;
662        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
663        data.writeStrongBinder(IInterface::asBinder(listener));
664        status_t status = remote()->transact(SET_LISTENER, data, &reply);
665        if (status != OK) {
666            return status;
667        }
668        return reply.readInt32();
669    }
670
671private:
672    void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
673        uint32_t size = reply.readInt32();
674        vector.insertAt((size_t)0, size);
675        reply.read(vector.editArray(), size);
676    }
677
678    void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
679        data.writeInt32(vector.size());
680        data.write(vector.array(), vector.size());
681    }
682
683    DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
684};
685
686IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
687
688////////////////////////////////////////////////////////////////////////////////
689
690void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
691    uint32_t size = data.readInt32();
692    if (vector.insertAt((size_t)0, size) < 0) {
693        vector.clear();
694    }
695    if (data.read(vector.editArray(), size) != NO_ERROR) {
696        vector.clear();
697        android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
698    }
699}
700
701void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
702    reply->writeInt32(vector.size());
703    reply->write(vector.array(), vector.size());
704}
705
706status_t BnDrm::onTransact(
707    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
708    switch (code) {
709        case INIT_CHECK:
710        {
711            CHECK_INTERFACE(IDrm, data, reply);
712            reply->writeInt32(initCheck());
713            return OK;
714        }
715
716        case IS_CRYPTO_SUPPORTED:
717        {
718            CHECK_INTERFACE(IDrm, data, reply);
719            uint8_t uuid[16];
720            data.read(uuid, sizeof(uuid));
721            String8 mimeType = data.readString8();
722            reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
723            return OK;
724        }
725
726        case CREATE_PLUGIN:
727        {
728            CHECK_INTERFACE(IDrm, data, reply);
729            uint8_t uuid[16];
730            data.read(uuid, sizeof(uuid));
731            String8 appPackageName = data.readString8();
732            reply->writeInt32(createPlugin(uuid, appPackageName));
733            return OK;
734        }
735
736        case DESTROY_PLUGIN:
737        {
738            CHECK_INTERFACE(IDrm, data, reply);
739            reply->writeInt32(destroyPlugin());
740            return OK;
741        }
742
743        case OPEN_SESSION:
744        {
745            CHECK_INTERFACE(IDrm, data, reply);
746            DrmPlugin::SecurityLevel level =
747                    static_cast<DrmPlugin::SecurityLevel>(data.readInt32());
748            Vector<uint8_t> sessionId;
749            status_t result = openSession(level, sessionId);
750            writeVector(reply, sessionId);
751            reply->writeInt32(result);
752            return OK;
753        }
754
755        case CLOSE_SESSION:
756        {
757            CHECK_INTERFACE(IDrm, data, reply);
758            Vector<uint8_t> sessionId;
759            readVector(data, sessionId);
760            reply->writeInt32(closeSession(sessionId));
761            return OK;
762        }
763
764        case GET_KEY_REQUEST:
765        {
766            CHECK_INTERFACE(IDrm, data, reply);
767            Vector<uint8_t> sessionId, initData;
768
769            readVector(data, sessionId);
770            readVector(data, initData);
771            String8 mimeType = data.readString8();
772            DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
773
774            KeyedVector<String8, String8> optionalParameters;
775            uint32_t count = data.readInt32();
776            for (size_t i = 0; i < count; ++i) {
777                String8 key, value;
778                key = data.readString8();
779                value = data.readString8();
780                optionalParameters.add(key, value);
781            }
782
783            Vector<uint8_t> request;
784            String8 defaultUrl;
785            DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
786
787            status_t result = getKeyRequest(sessionId, initData, mimeType,
788                    keyType, optionalParameters, request, defaultUrl,
789                    &keyRequestType);
790
791            writeVector(reply, request);
792            reply->writeString8(defaultUrl);
793            reply->writeInt32(static_cast<int32_t>(keyRequestType));
794            reply->writeInt32(result);
795            return OK;
796        }
797
798        case PROVIDE_KEY_RESPONSE:
799        {
800            CHECK_INTERFACE(IDrm, data, reply);
801            Vector<uint8_t> sessionId, response, keySetId;
802            readVector(data, sessionId);
803            readVector(data, response);
804            uint32_t result = provideKeyResponse(sessionId, response, keySetId);
805            writeVector(reply, keySetId);
806            reply->writeInt32(result);
807            return OK;
808        }
809
810        case REMOVE_KEYS:
811        {
812            CHECK_INTERFACE(IDrm, data, reply);
813            Vector<uint8_t> keySetId;
814            readVector(data, keySetId);
815            reply->writeInt32(removeKeys(keySetId));
816            return OK;
817        }
818
819        case RESTORE_KEYS:
820        {
821            CHECK_INTERFACE(IDrm, data, reply);
822            Vector<uint8_t> sessionId, keySetId;
823            readVector(data, sessionId);
824            readVector(data, keySetId);
825            reply->writeInt32(restoreKeys(sessionId, keySetId));
826            return OK;
827        }
828
829        case QUERY_KEY_STATUS:
830        {
831            CHECK_INTERFACE(IDrm, data, reply);
832            Vector<uint8_t> sessionId;
833            readVector(data, sessionId);
834            KeyedVector<String8, String8> infoMap;
835            status_t result = queryKeyStatus(sessionId, infoMap);
836            size_t count = infoMap.size();
837            reply->writeInt32(count);
838            for (size_t i = 0; i < count; ++i) {
839                reply->writeString8(infoMap.keyAt(i));
840                reply->writeString8(infoMap.valueAt(i));
841            }
842            reply->writeInt32(result);
843            return OK;
844        }
845
846        case GET_PROVISION_REQUEST:
847        {
848            CHECK_INTERFACE(IDrm, data, reply);
849            String8 certType = data.readString8();
850            String8 certAuthority = data.readString8();
851
852            Vector<uint8_t> request;
853            String8 defaultUrl;
854            status_t result = getProvisionRequest(certType, certAuthority,
855                                                  request, defaultUrl);
856            writeVector(reply, request);
857            reply->writeString8(defaultUrl);
858            reply->writeInt32(result);
859            return OK;
860        }
861
862        case PROVIDE_PROVISION_RESPONSE:
863        {
864            CHECK_INTERFACE(IDrm, data, reply);
865            Vector<uint8_t> response;
866            Vector<uint8_t> certificate;
867            Vector<uint8_t> wrappedKey;
868            readVector(data, response);
869            status_t result = provideProvisionResponse(response, certificate, wrappedKey);
870            writeVector(reply, certificate);
871            writeVector(reply, wrappedKey);
872            reply->writeInt32(result);
873            return OK;
874        }
875
876        case GET_SECURE_STOPS:
877        {
878            CHECK_INTERFACE(IDrm, data, reply);
879            List<Vector<uint8_t> > secureStops;
880            status_t result = getSecureStops(secureStops);
881            size_t count = secureStops.size();
882            reply->writeInt32(count);
883            List<Vector<uint8_t> >::iterator iter = secureStops.begin();
884            while(iter != secureStops.end()) {
885                size_t size = iter->size();
886                reply->writeInt32(size);
887                reply->write(iter->array(), iter->size());
888                iter++;
889            }
890            reply->writeInt32(result);
891            return OK;
892        }
893
894        case GET_SECURE_STOP_IDS:
895        {
896            CHECK_INTERFACE(IDrm, data, reply);
897            List<Vector<uint8_t> > secureStopIds;
898            status_t result = getSecureStopIds(secureStopIds);
899            size_t count = secureStopIds.size();
900            reply->writeInt32(count);
901            List<Vector<uint8_t> >::iterator iter = secureStopIds.begin();
902            while(iter != secureStopIds.end()) {
903                size_t size = iter->size();
904                reply->writeInt32(size);
905                reply->write(iter->array(), iter->size());
906                iter++;
907            }
908            reply->writeInt32(result);
909            return OK;
910        }
911
912        case GET_SECURE_STOP:
913        {
914            CHECK_INTERFACE(IDrm, data, reply);
915            Vector<uint8_t> ssid, secureStop;
916            readVector(data, ssid);
917            status_t result = getSecureStop(ssid, secureStop);
918            writeVector(reply, secureStop);
919            reply->writeInt32(result);
920            return OK;
921        }
922
923        case RELEASE_SECURE_STOPS:
924        {
925            CHECK_INTERFACE(IDrm, data, reply);
926            Vector<uint8_t> ssRelease;
927            readVector(data, ssRelease);
928            reply->writeInt32(releaseSecureStops(ssRelease));
929            return OK;
930        }
931
932        case REMOVE_SECURE_STOP:
933        {
934            CHECK_INTERFACE(IDrm, data, reply);
935            Vector<uint8_t> ssid;
936            readVector(data, ssid);
937            reply->writeInt32(removeSecureStop(ssid));
938            return OK;
939        }
940
941        case REMOVE_ALL_SECURE_STOPS:
942        {
943            CHECK_INTERFACE(IDrm, data, reply);
944            reply->writeInt32(removeAllSecureStops());
945            return OK;
946        }
947
948        case GET_HDCP_LEVELS:
949        {
950            CHECK_INTERFACE(IDrm, data, reply);
951            DrmPlugin::HdcpLevel connected = DrmPlugin::kHdcpLevelUnknown;
952            DrmPlugin::HdcpLevel max = DrmPlugin::kHdcpLevelUnknown;
953            status_t result = getHdcpLevels(&connected, &max);
954            reply->writeInt32(connected);
955            reply->writeInt32(max);
956            reply->writeInt32(result);
957            return OK;
958        }
959
960        case GET_NUMBER_OF_SESSIONS:
961        {
962            CHECK_INTERFACE(IDrm, data, reply);
963            uint32_t open = 0, max = 0;
964            status_t result = getNumberOfSessions(&open, &max);
965            reply->writeInt32(open);
966            reply->writeInt32(max);
967            reply->writeInt32(result);
968            return OK;
969        }
970
971        case GET_SECURITY_LEVEL:
972        {
973            CHECK_INTERFACE(IDrm, data, reply);
974            Vector<uint8_t> sessionId;
975            readVector(data, sessionId);
976            DrmPlugin::SecurityLevel level = DrmPlugin::kSecurityLevelUnknown;
977            status_t result = getSecurityLevel(sessionId, &level);
978            reply->writeInt32(level);
979            reply->writeInt32(result);
980            return OK;
981        }
982
983        case GET_PROPERTY_STRING:
984        {
985            CHECK_INTERFACE(IDrm, data, reply);
986            String8 name = data.readString8();
987            String8 value;
988            status_t result = getPropertyString(name, value);
989            reply->writeString8(value);
990            reply->writeInt32(result);
991            return OK;
992        }
993
994        case GET_PROPERTY_BYTE_ARRAY:
995        {
996            CHECK_INTERFACE(IDrm, data, reply);
997            String8 name = data.readString8();
998            Vector<uint8_t> value;
999            status_t result = getPropertyByteArray(name, value);
1000            writeVector(reply, value);
1001            reply->writeInt32(result);
1002            return OK;
1003        }
1004
1005        case SET_PROPERTY_STRING:
1006        {
1007            CHECK_INTERFACE(IDrm, data, reply);
1008            String8 name = data.readString8();
1009            String8 value = data.readString8();
1010            reply->writeInt32(setPropertyString(name, value));
1011            return OK;
1012        }
1013
1014        case SET_PROPERTY_BYTE_ARRAY:
1015        {
1016            CHECK_INTERFACE(IDrm, data, reply);
1017            String8 name = data.readString8();
1018            Vector<uint8_t> value;
1019            readVector(data, value);
1020            reply->writeInt32(setPropertyByteArray(name, value));
1021            return OK;
1022        }
1023
1024        case GET_METRICS:
1025        {
1026            CHECK_INTERFACE(IDrm, data, reply);
1027
1028            os::PersistableBundle metrics;
1029            status_t result = getMetrics(&metrics);
1030            // The reply data is ordered as
1031            // 1) 32 bit integer reply followed by
1032            // 2) Serialized PersistableBundle containing metrics.
1033            // Only write the metrics if the getMetrics result was
1034            // OK and we successfully added the status to reply.
1035            status_t parcel_result = reply->writeInt32(result);
1036            if (result == OK && parcel_result == OK) {
1037                parcel_result = metrics.writeToParcel(reply);
1038            }
1039            return parcel_result;
1040        }
1041
1042        case SET_CIPHER_ALGORITHM:
1043        {
1044            CHECK_INTERFACE(IDrm, data, reply);
1045            Vector<uint8_t> sessionId;
1046            readVector(data, sessionId);
1047            String8 algorithm = data.readString8();
1048            reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
1049            return OK;
1050        }
1051
1052        case SET_MAC_ALGORITHM:
1053        {
1054            CHECK_INTERFACE(IDrm, data, reply);
1055            Vector<uint8_t> sessionId;
1056            readVector(data, sessionId);
1057            String8 algorithm = data.readString8();
1058            reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
1059            return OK;
1060        }
1061
1062        case ENCRYPT:
1063        {
1064            CHECK_INTERFACE(IDrm, data, reply);
1065            Vector<uint8_t> sessionId, keyId, input, iv, output;
1066            readVector(data, sessionId);
1067            readVector(data, keyId);
1068            readVector(data, input);
1069            readVector(data, iv);
1070            uint32_t result = encrypt(sessionId, keyId, input, iv, output);
1071            writeVector(reply, output);
1072            reply->writeInt32(result);
1073            return OK;
1074        }
1075
1076        case DECRYPT:
1077        {
1078            CHECK_INTERFACE(IDrm, data, reply);
1079            Vector<uint8_t> sessionId, keyId, input, iv, output;
1080            readVector(data, sessionId);
1081            readVector(data, keyId);
1082            readVector(data, input);
1083            readVector(data, iv);
1084            uint32_t result = decrypt(sessionId, keyId, input, iv, output);
1085            writeVector(reply, output);
1086            reply->writeInt32(result);
1087            return OK;
1088        }
1089
1090        case SIGN:
1091        {
1092            CHECK_INTERFACE(IDrm, data, reply);
1093            Vector<uint8_t> sessionId, keyId, message, signature;
1094            readVector(data, sessionId);
1095            readVector(data, keyId);
1096            readVector(data, message);
1097            uint32_t result = sign(sessionId, keyId, message, signature);
1098            writeVector(reply, signature);
1099            reply->writeInt32(result);
1100            return OK;
1101        }
1102
1103        case VERIFY:
1104        {
1105            CHECK_INTERFACE(IDrm, data, reply);
1106            Vector<uint8_t> sessionId, keyId, message, signature;
1107            readVector(data, sessionId);
1108            readVector(data, keyId);
1109            readVector(data, message);
1110            readVector(data, signature);
1111            bool match = false;
1112            uint32_t result = verify(sessionId, keyId, message, signature, match);
1113            reply->writeInt32(match);
1114            reply->writeInt32(result);
1115            return OK;
1116        }
1117
1118        case SIGN_RSA:
1119        {
1120            CHECK_INTERFACE(IDrm, data, reply);
1121            Vector<uint8_t> sessionId, message, wrappedKey, signature;
1122            readVector(data, sessionId);
1123            String8 algorithm = data.readString8();
1124            readVector(data, message);
1125            readVector(data, wrappedKey);
1126            uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
1127            writeVector(reply, signature);
1128            reply->writeInt32(result);
1129            return OK;
1130        }
1131
1132    case SET_LISTENER: {
1133        CHECK_INTERFACE(IDrm, data, reply);
1134        sp<IDrmClient> listener =
1135            interface_cast<IDrmClient>(data.readStrongBinder());
1136        reply->writeInt32(setListener(listener));
1137        return NO_ERROR;
1138    } break;
1139
1140    default:
1141        return BBinder::onTransact(code, data, reply, flags);
1142    }
1143}
1144
1145}  // namespace android
1146