• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/IDrm.h>
23  #include <media/stagefright/MediaErrors.h>
24  #include <media/stagefright/foundation/ADebug.h>
25  #include <media/stagefright/foundation/AString.h>
26  
27  namespace android {
28  
29  enum {
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      SET_CIPHER_ALGORITHM,
50      SET_MAC_ALGORITHM,
51      ENCRYPT,
52      DECRYPT,
53      SIGN,
54      SIGN_RSA,
55      VERIFY,
56      SET_LISTENER,
57      GET_SECURE_STOP,
58      RELEASE_ALL_SECURE_STOPS
59  };
60  
61  struct BpDrm : public BpInterface<IDrm> {
BpDrmandroid::BpDrm62      BpDrm(const sp<IBinder> &impl)
63          : BpInterface<IDrm>(impl) {
64      }
65  
initCheckandroid::BpDrm66      virtual status_t initCheck() const {
67          Parcel data, reply;
68          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
69          status_t status = remote()->transact(INIT_CHECK, data, &reply);
70          if (status != OK) {
71              return status;
72          }
73  
74          return reply.readInt32();
75      }
76  
isCryptoSchemeSupportedandroid::BpDrm77      virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
78          Parcel data, reply;
79          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
80          data.write(uuid, 16);
81          data.writeString8(mimeType);
82          status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
83          if (status != OK) {
84              ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
85              return false;
86          }
87  
88          return reply.readInt32() != 0;
89      }
90  
createPluginandroid::BpDrm91      virtual status_t createPlugin(const uint8_t uuid[16]) {
92          Parcel data, reply;
93          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
94          data.write(uuid, 16);
95  
96          status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
97          if (status != OK) {
98              return status;
99          }
100  
101          return reply.readInt32();
102      }
103  
destroyPluginandroid::BpDrm104      virtual status_t destroyPlugin() {
105          Parcel data, reply;
106          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
107          status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
108          if (status != OK) {
109              return status;
110          }
111  
112          return reply.readInt32();
113      }
114  
openSessionandroid::BpDrm115      virtual status_t openSession(Vector<uint8_t> &sessionId) {
116          Parcel data, reply;
117          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
118  
119          status_t status = remote()->transact(OPEN_SESSION, data, &reply);
120          if (status != OK) {
121              return status;
122          }
123          readVector(reply, sessionId);
124  
125          return reply.readInt32();
126      }
127  
closeSessionandroid::BpDrm128      virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
129          Parcel data, reply;
130          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
131  
132          writeVector(data, sessionId);
133          status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
134          if (status != OK) {
135              return status;
136          }
137  
138          return reply.readInt32();
139      }
140  
141      virtual status_t
getKeyRequestandroid::BpDrm142          getKeyRequest(Vector<uint8_t> const &sessionId,
143                        Vector<uint8_t> const &initData,
144                        String8 const &mimeType, DrmPlugin::KeyType keyType,
145                        KeyedVector<String8, String8> const &optionalParameters,
146                        Vector<uint8_t> &request, String8 &defaultUrl,
147                        DrmPlugin::KeyRequestType *keyRequestType) {
148          Parcel data, reply;
149          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
150  
151          writeVector(data, sessionId);
152          writeVector(data, initData);
153          data.writeString8(mimeType);
154          data.writeInt32((uint32_t)keyType);
155  
156          data.writeInt32(optionalParameters.size());
157          for (size_t i = 0; i < optionalParameters.size(); ++i) {
158              data.writeString8(optionalParameters.keyAt(i));
159              data.writeString8(optionalParameters.valueAt(i));
160          }
161  
162          status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
163          if (status != OK) {
164              return status;
165          }
166  
167          readVector(reply, request);
168          defaultUrl = reply.readString8();
169          *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
170  
171          return reply.readInt32();
172      }
173  
provideKeyResponseandroid::BpDrm174      virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
175                                          Vector<uint8_t> const &response,
176                                          Vector<uint8_t> &keySetId) {
177          Parcel data, reply;
178          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
179          writeVector(data, sessionId);
180          writeVector(data, response);
181  
182          status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
183          if (status != OK) {
184              return status;
185          }
186  
187          readVector(reply, keySetId);
188  
189          return reply.readInt32();
190      }
191  
removeKeysandroid::BpDrm192      virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
193          Parcel data, reply;
194          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
195  
196          writeVector(data, keySetId);
197          status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
198          if (status != OK) {
199              return status;
200          }
201  
202          return reply.readInt32();
203      }
204  
restoreKeysandroid::BpDrm205      virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
206                                   Vector<uint8_t> const &keySetId) {
207          Parcel data, reply;
208          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
209  
210          writeVector(data, sessionId);
211          writeVector(data, keySetId);
212          status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
213          if (status != OK) {
214              return status;
215          }
216  
217          return reply.readInt32();
218      }
219  
queryKeyStatusandroid::BpDrm220      virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
221                                          KeyedVector<String8, String8> &infoMap) const {
222          Parcel data, reply;
223          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
224  
225          writeVector(data, sessionId);
226          status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
227          if (status != OK) {
228              return status;
229          }
230  
231          infoMap.clear();
232          size_t count = reply.readInt32();
233          for (size_t i = 0; i < count; i++) {
234              String8 key = reply.readString8();
235              String8 value = reply.readString8();
236              infoMap.add(key, value);
237          }
238          return reply.readInt32();
239      }
240  
getProvisionRequestandroid::BpDrm241      virtual status_t getProvisionRequest(String8 const &certType,
242                                           String8 const &certAuthority,
243                                           Vector<uint8_t> &request,
244                                           String8 &defaultUrl) {
245          Parcel data, reply;
246          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
247  
248          data.writeString8(certType);
249          data.writeString8(certAuthority);
250          status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
251          if (status != OK) {
252              return status;
253          }
254  
255          readVector(reply, request);
256          defaultUrl = reply.readString8();
257  
258          return reply.readInt32();
259      }
260  
provideProvisionResponseandroid::BpDrm261      virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
262                                                Vector<uint8_t> &certificate,
263                                                Vector<uint8_t> &wrappedKey) {
264          Parcel data, reply;
265          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
266  
267          writeVector(data, response);
268          status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
269          if (status != OK) {
270              return status;
271          }
272  
273          readVector(reply, certificate);
274          readVector(reply, wrappedKey);
275  
276          return reply.readInt32();
277      }
278  
getSecureStopsandroid::BpDrm279      virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
280          Parcel data, reply;
281          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
282  
283          status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
284          if (status != OK) {
285              return status;
286          }
287  
288          secureStops.clear();
289          uint32_t count = reply.readInt32();
290          for (size_t i = 0; i < count; i++) {
291              Vector<uint8_t> secureStop;
292              readVector(reply, secureStop);
293              secureStops.push_back(secureStop);
294          }
295          return reply.readInt32();
296      }
297  
getSecureStopandroid::BpDrm298      virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
299          Parcel data, reply;
300          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
301  
302          writeVector(data, ssid);
303          status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
304          if (status != OK) {
305              return status;
306          }
307  
308          readVector(reply, secureStop);
309          return reply.readInt32();
310      }
311  
releaseSecureStopsandroid::BpDrm312      virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
313          Parcel data, reply;
314          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
315  
316          writeVector(data, ssRelease);
317          status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
318          if (status != OK) {
319              return status;
320          }
321  
322          return reply.readInt32();
323      }
324  
releaseAllSecureStopsandroid::BpDrm325      virtual status_t releaseAllSecureStops() {
326          Parcel data, reply;
327          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
328  
329          status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
330          if (status != OK) {
331              return status;
332          }
333  
334          return reply.readInt32();
335      }
336  
getPropertyStringandroid::BpDrm337      virtual status_t getPropertyString(String8 const &name, String8 &value) const {
338          Parcel data, reply;
339          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
340  
341          data.writeString8(name);
342          status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
343          if (status != OK) {
344              return status;
345          }
346  
347          value = reply.readString8();
348          return reply.readInt32();
349      }
350  
getPropertyByteArrayandroid::BpDrm351      virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
352          Parcel data, reply;
353          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
354  
355          data.writeString8(name);
356          status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
357          if (status != OK) {
358              return status;
359          }
360  
361          readVector(reply, value);
362          return reply.readInt32();
363      }
364  
setPropertyStringandroid::BpDrm365      virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
366          Parcel data, reply;
367          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
368  
369          data.writeString8(name);
370          data.writeString8(value);
371          status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
372          if (status != OK) {
373              return status;
374          }
375  
376          return reply.readInt32();
377      }
378  
setPropertyByteArrayandroid::BpDrm379      virtual status_t setPropertyByteArray(String8 const &name,
380                                            Vector<uint8_t> const &value) const {
381          Parcel data, reply;
382          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
383  
384          data.writeString8(name);
385          writeVector(data, value);
386          status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
387          if (status != OK) {
388              return status;
389          }
390  
391          return reply.readInt32();
392      }
393  
394  
setCipherAlgorithmandroid::BpDrm395      virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
396                                          String8 const &algorithm) {
397          Parcel data, reply;
398          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
399  
400          writeVector(data, sessionId);
401          data.writeString8(algorithm);
402          status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
403          if (status != OK) {
404              return status;
405          }
406          return reply.readInt32();
407      }
408  
setMacAlgorithmandroid::BpDrm409      virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
410                                       String8 const &algorithm) {
411          Parcel data, reply;
412          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
413  
414          writeVector(data, sessionId);
415          data.writeString8(algorithm);
416          status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
417          if (status != OK) {
418              return status;
419          }
420          return reply.readInt32();
421      }
422  
encryptandroid::BpDrm423      virtual status_t encrypt(Vector<uint8_t> const &sessionId,
424                               Vector<uint8_t> const &keyId,
425                               Vector<uint8_t> const &input,
426                               Vector<uint8_t> const &iv,
427                               Vector<uint8_t> &output) {
428          Parcel data, reply;
429          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
430  
431          writeVector(data, sessionId);
432          writeVector(data, keyId);
433          writeVector(data, input);
434          writeVector(data, iv);
435  
436          status_t status = remote()->transact(ENCRYPT, data, &reply);
437          if (status != OK) {
438              return status;
439          }
440          readVector(reply, output);
441  
442          return reply.readInt32();
443      }
444  
decryptandroid::BpDrm445      virtual status_t decrypt(Vector<uint8_t> const &sessionId,
446                               Vector<uint8_t> const &keyId,
447                               Vector<uint8_t> const &input,
448                               Vector<uint8_t> const &iv,
449                               Vector<uint8_t> &output) {
450          Parcel data, reply;
451          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
452  
453          writeVector(data, sessionId);
454          writeVector(data, keyId);
455          writeVector(data, input);
456          writeVector(data, iv);
457  
458          status_t status = remote()->transact(DECRYPT, data, &reply);
459          if (status != OK) {
460              return status;
461          }
462          readVector(reply, output);
463  
464          return reply.readInt32();
465      }
466  
signandroid::BpDrm467      virtual status_t sign(Vector<uint8_t> const &sessionId,
468                            Vector<uint8_t> const &keyId,
469                            Vector<uint8_t> const &message,
470                            Vector<uint8_t> &signature) {
471          Parcel data, reply;
472          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
473  
474          writeVector(data, sessionId);
475          writeVector(data, keyId);
476          writeVector(data, message);
477  
478          status_t status = remote()->transact(SIGN, data, &reply);
479          if (status != OK) {
480              return status;
481          }
482          readVector(reply, signature);
483  
484          return reply.readInt32();
485      }
486  
verifyandroid::BpDrm487      virtual status_t verify(Vector<uint8_t> const &sessionId,
488                              Vector<uint8_t> const &keyId,
489                              Vector<uint8_t> const &message,
490                              Vector<uint8_t> const &signature,
491                              bool &match) {
492          Parcel data, reply;
493          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
494  
495          writeVector(data, sessionId);
496          writeVector(data, keyId);
497          writeVector(data, message);
498          writeVector(data, signature);
499  
500          status_t status = remote()->transact(VERIFY, data, &reply);
501          if (status != OK) {
502              return status;
503          }
504          match = (bool)reply.readInt32();
505          return reply.readInt32();
506      }
507  
signRSAandroid::BpDrm508      virtual status_t signRSA(Vector<uint8_t> const &sessionId,
509                               String8 const &algorithm,
510                               Vector<uint8_t> const &message,
511                               Vector<uint8_t> const &wrappedKey,
512                               Vector<uint8_t> &signature) {
513          Parcel data, reply;
514          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
515  
516          writeVector(data, sessionId);
517          data.writeString8(algorithm);
518          writeVector(data, message);
519          writeVector(data, wrappedKey);
520  
521          status_t status = remote()->transact(SIGN_RSA, data, &reply);
522          if (status != OK) {
523              return status;
524          }
525          readVector(reply, signature);
526  
527          return reply.readInt32();
528      }
529  
setListenerandroid::BpDrm530      virtual status_t setListener(const sp<IDrmClient>& listener) {
531          Parcel data, reply;
532          data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
533          data.writeStrongBinder(IInterface::asBinder(listener));
534          status_t status = remote()->transact(SET_LISTENER, data, &reply);
535          if (status != OK) {
536              return status;
537          }
538          return reply.readInt32();
539      }
540  
541  private:
readVectorandroid::BpDrm542      void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
543          uint32_t size = reply.readInt32();
544          vector.insertAt((size_t)0, size);
545          reply.read(vector.editArray(), size);
546      }
547  
writeVectorandroid::BpDrm548      void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
549          data.writeInt32(vector.size());
550          data.write(vector.array(), vector.size());
551      }
552  
553      DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
554  };
555  
556  IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
557  
558  ////////////////////////////////////////////////////////////////////////////////
559  
readVector(const Parcel & data,Vector<uint8_t> & vector) const560  void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
561      uint32_t size = data.readInt32();
562      vector.insertAt((size_t)0, size);
563      data.read(vector.editArray(), size);
564  }
565  
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const566  void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
567      reply->writeInt32(vector.size());
568      reply->write(vector.array(), vector.size());
569  }
570  
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)571  status_t BnDrm::onTransact(
572      uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
573      switch (code) {
574          case INIT_CHECK:
575          {
576              CHECK_INTERFACE(IDrm, data, reply);
577              reply->writeInt32(initCheck());
578              return OK;
579          }
580  
581          case IS_CRYPTO_SUPPORTED:
582          {
583              CHECK_INTERFACE(IDrm, data, reply);
584              uint8_t uuid[16];
585              data.read(uuid, sizeof(uuid));
586              String8 mimeType = data.readString8();
587              reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
588  
589              return OK;
590          }
591  
592          case CREATE_PLUGIN:
593          {
594              CHECK_INTERFACE(IDrm, data, reply);
595              uint8_t uuid[16];
596              data.read(uuid, sizeof(uuid));
597              reply->writeInt32(createPlugin(uuid));
598              return OK;
599          }
600  
601          case DESTROY_PLUGIN:
602          {
603              CHECK_INTERFACE(IDrm, data, reply);
604              reply->writeInt32(destroyPlugin());
605              return OK;
606          }
607  
608          case OPEN_SESSION:
609          {
610              CHECK_INTERFACE(IDrm, data, reply);
611              Vector<uint8_t> sessionId;
612              status_t result = openSession(sessionId);
613              writeVector(reply, sessionId);
614              reply->writeInt32(result);
615              return OK;
616          }
617  
618          case CLOSE_SESSION:
619          {
620              CHECK_INTERFACE(IDrm, data, reply);
621              Vector<uint8_t> sessionId;
622              readVector(data, sessionId);
623              reply->writeInt32(closeSession(sessionId));
624              return OK;
625          }
626  
627          case GET_KEY_REQUEST:
628          {
629              CHECK_INTERFACE(IDrm, data, reply);
630              Vector<uint8_t> sessionId, initData;
631  
632              readVector(data, sessionId);
633              readVector(data, initData);
634              String8 mimeType = data.readString8();
635              DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
636  
637              KeyedVector<String8, String8> optionalParameters;
638              uint32_t count = data.readInt32();
639              for (size_t i = 0; i < count; ++i) {
640                  String8 key, value;
641                  key = data.readString8();
642                  value = data.readString8();
643                  optionalParameters.add(key, value);
644              }
645  
646              Vector<uint8_t> request;
647              String8 defaultUrl;
648              DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
649  
650              status_t result = getKeyRequest(sessionId, initData, mimeType,
651                      keyType, optionalParameters, request, defaultUrl,
652                      &keyRequestType);
653  
654              writeVector(reply, request);
655              reply->writeString8(defaultUrl);
656              reply->writeInt32(static_cast<int32_t>(keyRequestType));
657              reply->writeInt32(result);
658              return OK;
659          }
660  
661          case PROVIDE_KEY_RESPONSE:
662          {
663              CHECK_INTERFACE(IDrm, data, reply);
664              Vector<uint8_t> sessionId, response, keySetId;
665              readVector(data, sessionId);
666              readVector(data, response);
667              uint32_t result = provideKeyResponse(sessionId, response, keySetId);
668              writeVector(reply, keySetId);
669              reply->writeInt32(result);
670              return OK;
671          }
672  
673          case REMOVE_KEYS:
674          {
675              CHECK_INTERFACE(IDrm, data, reply);
676              Vector<uint8_t> keySetId;
677              readVector(data, keySetId);
678              reply->writeInt32(removeKeys(keySetId));
679              return OK;
680          }
681  
682          case RESTORE_KEYS:
683          {
684              CHECK_INTERFACE(IDrm, data, reply);
685              Vector<uint8_t> sessionId, keySetId;
686              readVector(data, sessionId);
687              readVector(data, keySetId);
688              reply->writeInt32(restoreKeys(sessionId, keySetId));
689              return OK;
690          }
691  
692          case QUERY_KEY_STATUS:
693          {
694              CHECK_INTERFACE(IDrm, data, reply);
695              Vector<uint8_t> sessionId;
696              readVector(data, sessionId);
697              KeyedVector<String8, String8> infoMap;
698              status_t result = queryKeyStatus(sessionId, infoMap);
699              size_t count = infoMap.size();
700              reply->writeInt32(count);
701              for (size_t i = 0; i < count; ++i) {
702                  reply->writeString8(infoMap.keyAt(i));
703                  reply->writeString8(infoMap.valueAt(i));
704              }
705              reply->writeInt32(result);
706              return OK;
707          }
708  
709          case GET_PROVISION_REQUEST:
710          {
711              CHECK_INTERFACE(IDrm, data, reply);
712              String8 certType = data.readString8();
713              String8 certAuthority = data.readString8();
714  
715              Vector<uint8_t> request;
716              String8 defaultUrl;
717              status_t result = getProvisionRequest(certType, certAuthority,
718                                                    request, defaultUrl);
719              writeVector(reply, request);
720              reply->writeString8(defaultUrl);
721              reply->writeInt32(result);
722              return OK;
723          }
724  
725          case PROVIDE_PROVISION_RESPONSE:
726          {
727              CHECK_INTERFACE(IDrm, data, reply);
728              Vector<uint8_t> response;
729              Vector<uint8_t> certificate;
730              Vector<uint8_t> wrappedKey;
731              readVector(data, response);
732              status_t result = provideProvisionResponse(response, certificate, wrappedKey);
733              writeVector(reply, certificate);
734              writeVector(reply, wrappedKey);
735              reply->writeInt32(result);
736              return OK;
737          }
738  
739          case GET_SECURE_STOPS:
740          {
741              CHECK_INTERFACE(IDrm, data, reply);
742              List<Vector<uint8_t> > secureStops;
743              status_t result = getSecureStops(secureStops);
744              size_t count = secureStops.size();
745              reply->writeInt32(count);
746              List<Vector<uint8_t> >::iterator iter = secureStops.begin();
747              while(iter != secureStops.end()) {
748                  size_t size = iter->size();
749                  reply->writeInt32(size);
750                  reply->write(iter->array(), iter->size());
751                  iter++;
752              }
753              reply->writeInt32(result);
754              return OK;
755          }
756  
757          case GET_SECURE_STOP:
758          {
759              CHECK_INTERFACE(IDrm, data, reply);
760              Vector<uint8_t> ssid, secureStop;
761              readVector(data, ssid);
762              status_t result = getSecureStop(ssid, secureStop);
763              writeVector(reply, secureStop);
764              reply->writeInt32(result);
765              return OK;
766          }
767  
768          case RELEASE_SECURE_STOPS:
769          {
770              CHECK_INTERFACE(IDrm, data, reply);
771              Vector<uint8_t> ssRelease;
772              readVector(data, ssRelease);
773              reply->writeInt32(releaseSecureStops(ssRelease));
774              return OK;
775          }
776  
777          case RELEASE_ALL_SECURE_STOPS:
778          {
779              CHECK_INTERFACE(IDrm, data, reply);
780              reply->writeInt32(releaseAllSecureStops());
781              return OK;
782          }
783  
784          case GET_PROPERTY_STRING:
785          {
786              CHECK_INTERFACE(IDrm, data, reply);
787              String8 name = data.readString8();
788              String8 value;
789              status_t result = getPropertyString(name, value);
790              reply->writeString8(value);
791              reply->writeInt32(result);
792              return OK;
793          }
794  
795          case GET_PROPERTY_BYTE_ARRAY:
796          {
797              CHECK_INTERFACE(IDrm, data, reply);
798              String8 name = data.readString8();
799              Vector<uint8_t> value;
800              status_t result = getPropertyByteArray(name, value);
801              writeVector(reply, value);
802              reply->writeInt32(result);
803              return OK;
804          }
805  
806          case SET_PROPERTY_STRING:
807          {
808              CHECK_INTERFACE(IDrm, data, reply);
809              String8 name = data.readString8();
810              String8 value = data.readString8();
811              reply->writeInt32(setPropertyString(name, value));
812              return OK;
813          }
814  
815          case SET_PROPERTY_BYTE_ARRAY:
816          {
817              CHECK_INTERFACE(IDrm, data, reply);
818              String8 name = data.readString8();
819              Vector<uint8_t> value;
820              readVector(data, value);
821              reply->writeInt32(setPropertyByteArray(name, value));
822              return OK;
823          }
824  
825          case SET_CIPHER_ALGORITHM:
826          {
827              CHECK_INTERFACE(IDrm, data, reply);
828              Vector<uint8_t> sessionId;
829              readVector(data, sessionId);
830              String8 algorithm = data.readString8();
831              reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
832              return OK;
833          }
834  
835          case SET_MAC_ALGORITHM:
836          {
837              CHECK_INTERFACE(IDrm, data, reply);
838              Vector<uint8_t> sessionId;
839              readVector(data, sessionId);
840              String8 algorithm = data.readString8();
841              reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
842              return OK;
843          }
844  
845          case ENCRYPT:
846          {
847              CHECK_INTERFACE(IDrm, data, reply);
848              Vector<uint8_t> sessionId, keyId, input, iv, output;
849              readVector(data, sessionId);
850              readVector(data, keyId);
851              readVector(data, input);
852              readVector(data, iv);
853              uint32_t result = encrypt(sessionId, keyId, input, iv, output);
854              writeVector(reply, output);
855              reply->writeInt32(result);
856              return OK;
857          }
858  
859          case DECRYPT:
860          {
861              CHECK_INTERFACE(IDrm, data, reply);
862              Vector<uint8_t> sessionId, keyId, input, iv, output;
863              readVector(data, sessionId);
864              readVector(data, keyId);
865              readVector(data, input);
866              readVector(data, iv);
867              uint32_t result = decrypt(sessionId, keyId, input, iv, output);
868              writeVector(reply, output);
869              reply->writeInt32(result);
870              return OK;
871          }
872  
873          case SIGN:
874          {
875              CHECK_INTERFACE(IDrm, data, reply);
876              Vector<uint8_t> sessionId, keyId, message, signature;
877              readVector(data, sessionId);
878              readVector(data, keyId);
879              readVector(data, message);
880              uint32_t result = sign(sessionId, keyId, message, signature);
881              writeVector(reply, signature);
882              reply->writeInt32(result);
883              return OK;
884          }
885  
886          case VERIFY:
887          {
888              CHECK_INTERFACE(IDrm, data, reply);
889              Vector<uint8_t> sessionId, keyId, message, signature;
890              readVector(data, sessionId);
891              readVector(data, keyId);
892              readVector(data, message);
893              readVector(data, signature);
894              bool match;
895              uint32_t result = verify(sessionId, keyId, message, signature, match);
896              reply->writeInt32(match);
897              reply->writeInt32(result);
898              return OK;
899          }
900  
901          case SIGN_RSA:
902          {
903              CHECK_INTERFACE(IDrm, data, reply);
904              Vector<uint8_t> sessionId, message, wrappedKey, signature;
905              readVector(data, sessionId);
906              String8 algorithm = data.readString8();
907              readVector(data, message);
908              readVector(data, wrappedKey);
909              uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
910              writeVector(reply, signature);
911              reply->writeInt32(result);
912              return OK;
913          }
914  
915      case SET_LISTENER: {
916          CHECK_INTERFACE(IDrm, data, reply);
917          sp<IDrmClient> listener =
918              interface_cast<IDrmClient>(data.readStrongBinder());
919          reply->writeInt32(setListener(listener));
920          return NO_ERROR;
921      } break;
922  
923      default:
924          return BBinder::onTransact(code, data, reply, flags);
925      }
926  }
927  
928  }  // namespace android
929