• 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 "MockDrmCryptoPlugin"
19 #include <utils/Log.h>
20 
21 
22 #include "drm/DrmAPI.h"
23 #include "MockDrmCryptoPlugin.h"
24 #include "media/stagefright/MediaErrors.h"
25 
26 using namespace android;
27 
28 // Shared library entry point
createDrmFactory()29 DrmFactory *createDrmFactory()
30 {
31     return new MockDrmFactory();
32 }
33 
34 // Shared library entry point
createCryptoFactory()35 CryptoFactory *createCryptoFactory()
36 {
37     return new MockCryptoFactory();
38 }
39 
40 const uint8_t mock_uuid[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
41                                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
42 
43 namespace android {
44 
45     // MockDrmFactory
isCryptoSchemeSupported(const uint8_t uuid[16])46     bool MockDrmFactory::isCryptoSchemeSupported(const uint8_t uuid[16])
47     {
48         return (!memcmp(uuid, mock_uuid, sizeof(uuid)));
49     }
50 
isContentTypeSupported(const String8 & mimeType)51     bool MockDrmFactory::isContentTypeSupported(const String8 &mimeType)
52     {
53         if (mimeType != "video/mp4") {
54             return false;
55         }
56         return true;
57     }
58 
createDrmPlugin(const uint8_t uuid[16],DrmPlugin ** plugin)59     status_t MockDrmFactory::createDrmPlugin(const uint8_t uuid[16], DrmPlugin **plugin)
60     {
61         *plugin = new MockDrmPlugin();
62         return OK;
63     }
64 
65     // MockCryptoFactory
isCryptoSchemeSupported(const uint8_t uuid[16]) const66     bool MockCryptoFactory::isCryptoSchemeSupported(const uint8_t uuid[16]) const
67     {
68         return (!memcmp(uuid, mock_uuid, sizeof(uuid)));
69     }
70 
createPlugin(const uint8_t uuid[16],const void * data,size_t size,CryptoPlugin ** plugin)71     status_t MockCryptoFactory::createPlugin(const uint8_t uuid[16], const void *data,
72                                              size_t size, CryptoPlugin **plugin)
73     {
74         *plugin = new MockCryptoPlugin();
75         return OK;
76     }
77 
78 
79     // MockDrmPlugin methods
80 
openSession(Vector<uint8_t> & sessionId)81     status_t MockDrmPlugin::openSession(Vector<uint8_t> &sessionId)
82     {
83         const size_t kSessionIdSize = 8;
84 
85         Mutex::Autolock lock(mLock);
86         for (size_t i = 0; i < kSessionIdSize / sizeof(long); i++) {
87             long r = random();
88             sessionId.appendArray((uint8_t *)&r, sizeof(long));
89         }
90         mSessions.add(sessionId);
91 
92         ALOGD("MockDrmPlugin::openSession() -> %s", vectorToString(sessionId).string());
93         return OK;
94     }
95 
closeSession(Vector<uint8_t> const & sessionId)96     status_t MockDrmPlugin::closeSession(Vector<uint8_t> const &sessionId)
97     {
98         Mutex::Autolock lock(mLock);
99         ALOGD("MockDrmPlugin::closeSession(%s)", vectorToString(sessionId).string());
100         ssize_t index = findSession(sessionId);
101         if (index == kNotFound) {
102             ALOGD("Invalid sessionId");
103             return BAD_VALUE;
104         }
105         mSessions.removeAt(index);
106         return OK;
107     }
108 
109 
getKeyRequest(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & initData,String8 const & mimeType,KeyType keyType,KeyedVector<String8,String8> const & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl)110     status_t MockDrmPlugin::getKeyRequest(Vector<uint8_t> const &sessionId,
111                                           Vector<uint8_t> const &initData,
112                                           String8 const &mimeType, KeyType keyType,
113                                           KeyedVector<String8, String8> const &optionalParameters,
114                                           Vector<uint8_t> &request, String8 &defaultUrl)
115     {
116         Mutex::Autolock lock(mLock);
117         ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s"
118               ", keyType=%d, optionalParameters=%s))",
119               vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(),
120               keyType, stringMapToString(optionalParameters).string());
121 
122         ssize_t index = findSession(sessionId);
123         if (index == kNotFound) {
124             ALOGD("Invalid sessionId");
125             return BAD_VALUE;
126         }
127 
128         // Properties used in mock test, set by mock plugin and verifed cts test app
129         //   byte[] initData           -> mock-initdata
130         //   string mimeType           -> mock-mimetype
131         //   string keyType            -> mock-keytype
132         //   string optionalParameters -> mock-optparams formatted as {key1,value1},{key2,value2}
133 
134         mByteArrayProperties.add(String8("mock-initdata"), initData);
135         mStringProperties.add(String8("mock-mimetype"), mimeType);
136 
137         String8 keyTypeStr;
138         keyTypeStr.appendFormat("%d", (int)keyType);
139         mStringProperties.add(String8("mock-keytype"), keyTypeStr);
140 
141         String8 params;
142         for (size_t i = 0; i < optionalParameters.size(); i++) {
143             params.appendFormat("%s{%s,%s}", i ? "," : "",
144                                 optionalParameters.keyAt(i).string(),
145                                 optionalParameters.valueAt(i).string());
146         }
147         mStringProperties.add(String8("mock-optparams"), params);
148 
149         // Properties used in mock test, set by cts test app returned from mock plugin
150         //   byte[] mock-request       -> request
151         //   string mock-default-url   -> defaultUrl
152 
153         index = mByteArrayProperties.indexOfKey(String8("mock-request"));
154         if (index < 0) {
155             ALOGD("Missing 'mock-request' parameter for mock");
156             return BAD_VALUE;
157         } else {
158             request = mByteArrayProperties.valueAt(index);
159         }
160 
161         index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
162         if (index < 0) {
163             ALOGD("Missing 'mock-defaultUrl' parameter for mock");
164             return BAD_VALUE;
165         } else {
166             defaultUrl = mStringProperties.valueAt(index);
167         }
168         return OK;
169     }
170 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)171     status_t MockDrmPlugin::provideKeyResponse(Vector<uint8_t> const &sessionId,
172                                                Vector<uint8_t> const &response,
173                                                Vector<uint8_t> &keySetId)
174     {
175         Mutex::Autolock lock(mLock);
176         ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)",
177               vectorToString(sessionId).string(), vectorToString(response).string());
178         ssize_t index = findSession(sessionId);
179         if (index == kNotFound) {
180             ALOGD("Invalid sessionId");
181             return BAD_VALUE;
182         }
183         if (response.size() == 0) {
184             return BAD_VALUE;
185         }
186 
187         // Properties used in mock test, set by mock plugin and verifed cts test app
188         //   byte[] response            -> mock-response
189         mByteArrayProperties.add(String8("mock-response"), response);
190 
191         const size_t kKeySetIdSize = 8;
192 
193         for (size_t i = 0; i < kKeySetIdSize / sizeof(long); i++) {
194             long r = random();
195             keySetId.appendArray((uint8_t *)&r, sizeof(long));
196         }
197         mKeySets.add(keySetId);
198 
199         return OK;
200     }
201 
removeKeys(Vector<uint8_t> const & keySetId)202     status_t MockDrmPlugin::removeKeys(Vector<uint8_t> const &keySetId)
203     {
204         Mutex::Autolock lock(mLock);
205         ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)",
206               vectorToString(keySetId).string());
207 
208         ssize_t index = findKeySet(keySetId);
209         if (index == kNotFound) {
210             ALOGD("Invalid keySetId");
211             return BAD_VALUE;
212         }
213         mKeySets.removeAt(index);
214 
215         return OK;
216     }
217 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)218     status_t MockDrmPlugin::restoreKeys(Vector<uint8_t> const &sessionId,
219                                         Vector<uint8_t> const &keySetId)
220     {
221         Mutex::Autolock lock(mLock);
222         ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)",
223               vectorToString(sessionId).string(),
224               vectorToString(keySetId).string());
225         ssize_t index = findSession(sessionId);
226         if (index == kNotFound) {
227             ALOGD("Invalid sessionId");
228             return BAD_VALUE;
229         }
230 
231         index = findKeySet(keySetId);
232         if (index == kNotFound) {
233             ALOGD("Invalid keySetId");
234             return BAD_VALUE;
235         }
236 
237         return OK;
238     }
239 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const240     status_t MockDrmPlugin::queryKeyStatus(Vector<uint8_t> const &sessionId,
241                                                KeyedVector<String8, String8> &infoMap) const
242     {
243         ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)",
244               vectorToString(sessionId).string());
245 
246         ssize_t index = findSession(sessionId);
247         if (index == kNotFound) {
248             ALOGD("Invalid sessionId");
249             return BAD_VALUE;
250         }
251 
252         infoMap.add(String8("purchaseDuration"), String8("1000"));
253         infoMap.add(String8("licenseDuration"), String8("100"));
254         return OK;
255     }
256 
getProvisionRequest(Vector<uint8_t> & request,String8 & defaultUrl)257     status_t MockDrmPlugin::getProvisionRequest(Vector<uint8_t> &request,
258                                                 String8 &defaultUrl)
259     {
260         Mutex::Autolock lock(mLock);
261         ALOGD("MockDrmPlugin::getProvisionRequest()");
262 
263         // Properties used in mock test, set by cts test app returned from mock plugin
264         //   byte[] mock-request       -> request
265         //   string mock-default-url   -> defaultUrl
266 
267         ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-request"));
268         if (index < 0) {
269             ALOGD("Missing 'mock-request' parameter for mock");
270             return BAD_VALUE;
271         } else {
272             request = mByteArrayProperties.valueAt(index);
273         }
274 
275         index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
276         if (index < 0) {
277             ALOGD("Missing 'mock-defaultUrl' parameter for mock");
278             return BAD_VALUE;
279         } else {
280             defaultUrl = mStringProperties.valueAt(index);
281         }
282         return OK;
283     }
284 
provideProvisionResponse(Vector<uint8_t> const & response)285     status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response)
286     {
287         Mutex::Autolock lock(mLock);
288         ALOGD("MockDrmPlugin::provideProvisionResponse(%s)",
289               vectorToString(response).string());
290 
291         // Properties used in mock test, set by mock plugin and verifed cts test app
292         //   byte[] response            -> mock-response
293 
294         mByteArrayProperties.add(String8("mock-response"), response);
295         return OK;
296     }
297 
getSecureStops(List<Vector<uint8_t>> & secureStops)298     status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops)
299     {
300         Mutex::Autolock lock(mLock);
301         ALOGD("MockDrmPlugin::getSecureStops()");
302 
303         // Properties used in mock test, set by cts test app returned from mock plugin
304         //   byte[] mock-secure-stop1  -> first secure stop in list
305         //   byte[] mock-secure-stop2  -> second secure stop in list
306 
307         Vector<uint8_t> ss1, ss2;
308         ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop1"));
309         if (index < 0) {
310             ALOGD("Missing 'mock-secure-stop1' parameter for mock");
311             return BAD_VALUE;
312         } else {
313             ss1 = mByteArrayProperties.valueAt(index);
314         }
315 
316         index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop2"));
317         if (index < 0) {
318             ALOGD("Missing 'mock-secure-stop2' parameter for mock");
319             return BAD_VALUE;
320         } else {
321             ss2 = mByteArrayProperties.valueAt(index);
322         }
323 
324         secureStops.push_back(ss1);
325         secureStops.push_back(ss2);
326         return OK;
327     }
328 
releaseSecureStops(Vector<uint8_t> const & ssRelease)329     status_t MockDrmPlugin::releaseSecureStops(Vector<uint8_t> const &ssRelease)
330     {
331         Mutex::Autolock lock(mLock);
332         ALOGD("MockDrmPlugin::releaseSecureStops(%s)",
333               vectorToString(ssRelease).string());
334 
335         // Properties used in mock test, set by mock plugin and verifed cts test app
336         //   byte[] secure-stop-release  -> mock-ssrelease
337         mByteArrayProperties.add(String8("mock-ssrelease"), ssRelease);
338 
339         return OK;
340     }
341 
getPropertyString(String8 const & name,String8 & value) const342     status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const
343     {
344         ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string());
345         ssize_t index = mStringProperties.indexOfKey(name);
346         if (index < 0) {
347             ALOGD("no property for '%s'", name.string());
348             return BAD_VALUE;
349         }
350         value = mStringProperties.valueAt(index);
351         return OK;
352     }
353 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const354     status_t MockDrmPlugin::getPropertyByteArray(String8 const &name,
355                                                  Vector<uint8_t> &value) const
356     {
357         ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string());
358         ssize_t index = mByteArrayProperties.indexOfKey(name);
359         if (index < 0) {
360             ALOGD("no property for '%s'", name.string());
361             return BAD_VALUE;
362         }
363         value = mByteArrayProperties.valueAt(index);
364         return OK;
365     }
366 
setPropertyString(String8 const & name,String8 const & value)367     status_t MockDrmPlugin::setPropertyString(String8 const &name,
368                                               String8 const &value)
369     {
370         Mutex::Autolock lock(mLock);
371         ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)",
372               name.string(), value.string());
373 
374         if (name == "mock-send-event") {
375             unsigned code, extra;
376             sscanf(value.string(), "%d %d", &code, &extra);
377             DrmPlugin::EventType eventType = (DrmPlugin::EventType)code;
378 
379             Vector<uint8_t> const *pSessionId = NULL;
380             ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
381             if (index >= 0) {
382                 pSessionId = &mByteArrayProperties[index];
383             }
384 
385             Vector<uint8_t> const *pData = NULL;
386             index = mByteArrayProperties.indexOfKey(String8("mock-event-data"));
387             if (index >= 0) {
388                 pData = &mByteArrayProperties[index];
389             }
390             ALOGD("sending event from mock drm plugin: %d %d %s %s",
391                   (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}",
392                   pData ? vectorToString(*pData) : "{}");
393 
394             sendEvent(eventType, extra, pSessionId, pData);
395         } else {
396             mStringProperties.add(name, value);
397         }
398         return OK;
399     }
400 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value)401     status_t MockDrmPlugin::setPropertyByteArray(String8 const &name,
402                                                  Vector<uint8_t> const &value)
403     {
404         Mutex::Autolock lock(mLock);
405         ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)",
406               name.string(), vectorToString(value).string());
407         mByteArrayProperties.add(name, value);
408         return OK;
409     }
410 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)411     status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
412                                                String8 const &algorithm)
413     {
414         Mutex::Autolock lock(mLock);
415 
416         ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)",
417               vectorToString(sessionId).string(), algorithm.string());
418 
419         ssize_t index = findSession(sessionId);
420         if (index == kNotFound) {
421             ALOGD("Invalid sessionId");
422             return BAD_VALUE;
423         }
424 
425         if (algorithm == "AES/CBC/NoPadding") {
426             return OK;
427         }
428         return BAD_VALUE;
429     }
430 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)431     status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId,
432                                             String8 const &algorithm)
433     {
434         Mutex::Autolock lock(mLock);
435 
436         ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)",
437               vectorToString(sessionId).string(), algorithm.string());
438 
439         ssize_t index = findSession(sessionId);
440         if (index == kNotFound) {
441             ALOGD("Invalid sessionId");
442             return BAD_VALUE;
443         }
444 
445         if (algorithm == "HmacSHA256") {
446             return OK;
447         }
448         return BAD_VALUE;
449     }
450 
encrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)451     status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId,
452                                     Vector<uint8_t> const &keyId,
453                                     Vector<uint8_t> const &input,
454                                     Vector<uint8_t> const &iv,
455                                     Vector<uint8_t> &output)
456     {
457         Mutex::Autolock lock(mLock);
458         ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
459               vectorToString(sessionId).string(),
460               vectorToString(keyId).string(),
461               vectorToString(input).string(),
462               vectorToString(iv).string());
463 
464         ssize_t index = findSession(sessionId);
465         if (index == kNotFound) {
466             ALOGD("Invalid sessionId");
467             return BAD_VALUE;
468         }
469 
470         // Properties used in mock test, set by mock plugin and verifed cts test app
471         //   byte[] keyId              -> mock-keyid
472         //   byte[] input              -> mock-input
473         //   byte[] iv                 -> mock-iv
474         mByteArrayProperties.add(String8("mock-keyid"), keyId);
475         mByteArrayProperties.add(String8("mock-input"), input);
476         mByteArrayProperties.add(String8("mock-iv"), iv);
477 
478         // Properties used in mock test, set by cts test app returned from mock plugin
479         //   byte[] mock-output        -> output
480         index = mByteArrayProperties.indexOfKey(String8("mock-output"));
481         if (index < 0) {
482             ALOGD("Missing 'mock-request' parameter for mock");
483             return BAD_VALUE;
484         } else {
485             output = mByteArrayProperties.valueAt(index);
486         }
487         return OK;
488     }
489 
decrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)490     status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId,
491                                     Vector<uint8_t> const &keyId,
492                                     Vector<uint8_t> const &input,
493                                     Vector<uint8_t> const &iv,
494                                     Vector<uint8_t> &output)
495     {
496         Mutex::Autolock lock(mLock);
497         ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
498               vectorToString(sessionId).string(),
499               vectorToString(keyId).string(),
500               vectorToString(input).string(),
501               vectorToString(iv).string());
502 
503         ssize_t index = findSession(sessionId);
504         if (index == kNotFound) {
505             ALOGD("Invalid sessionId");
506             return BAD_VALUE;
507         }
508 
509         // Properties used in mock test, set by mock plugin and verifed cts test app
510         //   byte[] keyId              -> mock-keyid
511         //   byte[] input              -> mock-input
512         //   byte[] iv                 -> mock-iv
513         mByteArrayProperties.add(String8("mock-keyid"), keyId);
514         mByteArrayProperties.add(String8("mock-input"), input);
515         mByteArrayProperties.add(String8("mock-iv"), iv);
516 
517         // Properties used in mock test, set by cts test app returned from mock plugin
518         //   byte[] mock-output        -> output
519         index = mByteArrayProperties.indexOfKey(String8("mock-output"));
520         if (index < 0) {
521             ALOGD("Missing 'mock-request' parameter for mock");
522             return BAD_VALUE;
523         } else {
524             output = mByteArrayProperties.valueAt(index);
525         }
526         return OK;
527     }
528 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)529     status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId,
530                                  Vector<uint8_t> const &keyId,
531                                  Vector<uint8_t> const &message,
532                                  Vector<uint8_t> &signature)
533     {
534         Mutex::Autolock lock(mLock);
535         ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)",
536               vectorToString(sessionId).string(),
537               vectorToString(keyId).string(),
538               vectorToString(message).string());
539 
540         ssize_t index = findSession(sessionId);
541         if (index == kNotFound) {
542             ALOGD("Invalid sessionId");
543             return BAD_VALUE;
544         }
545 
546         // Properties used in mock test, set by mock plugin and verifed cts test app
547         //   byte[] keyId              -> mock-keyid
548         //   byte[] message            -> mock-message
549         mByteArrayProperties.add(String8("mock-keyid"), keyId);
550         mByteArrayProperties.add(String8("mock-message"), message);
551 
552         // Properties used in mock test, set by cts test app returned from mock plugin
553         //   byte[] mock-signature        -> signature
554         index = mByteArrayProperties.indexOfKey(String8("mock-signature"));
555         if (index < 0) {
556             ALOGD("Missing 'mock-request' parameter for mock");
557             return BAD_VALUE;
558         } else {
559             signature = mByteArrayProperties.valueAt(index);
560         }
561         return OK;
562     }
563 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)564     status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId,
565                                    Vector<uint8_t> const &keyId,
566                                    Vector<uint8_t> const &message,
567                                    Vector<uint8_t> const &signature,
568                                    bool &match)
569     {
570         Mutex::Autolock lock(mLock);
571         ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)",
572               vectorToString(sessionId).string(),
573               vectorToString(keyId).string(),
574               vectorToString(message).string(),
575               vectorToString(signature).string());
576 
577         ssize_t index = findSession(sessionId);
578         if (index == kNotFound) {
579             ALOGD("Invalid sessionId");
580             return BAD_VALUE;
581         }
582 
583         // Properties used in mock test, set by mock plugin and verifed cts test app
584         //   byte[] keyId              -> mock-keyid
585         //   byte[] message            -> mock-message
586         //   byte[] signature          -> mock-signature
587         mByteArrayProperties.add(String8("mock-keyid"), keyId);
588         mByteArrayProperties.add(String8("mock-message"), message);
589         mByteArrayProperties.add(String8("mock-signature"), signature);
590 
591         // Properties used in mock test, set by cts test app returned from mock plugin
592         //   String mock-match "1" or "0"         -> match
593         index = mStringProperties.indexOfKey(String8("mock-match"));
594         if (index < 0) {
595             ALOGD("Missing 'mock-request' parameter for mock");
596             return BAD_VALUE;
597         } else {
598             match = atol(mStringProperties.valueAt(index).string());
599         }
600         return OK;
601     }
602 
findSession(Vector<uint8_t> const & sessionId) const603     ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const
604     {
605         ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size());
606         for (size_t i = 0; i < mSessions.size(); ++i) {
607             if (memcmp(mSessions[i].array(), sessionId.array(), sessionId.size()) == 0) {
608                 return i;
609             }
610         }
611         return kNotFound;
612     }
613 
findKeySet(Vector<uint8_t> const & keySetId) const614     ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const
615     {
616         ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size());
617         for (size_t i = 0; i < mKeySets.size(); ++i) {
618             if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) {
619                 return i;
620             }
621         }
622         return kNotFound;
623     }
624 
625 
626     // Conversion utilities
vectorToString(Vector<uint8_t> const & vector) const627     String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const
628     {
629         return arrayToString(vector.array(), vector.size());
630     }
631 
arrayToString(uint8_t const * array,size_t len) const632     String8 MockDrmPlugin::arrayToString(uint8_t const *array, size_t len) const
633     {
634         String8 result("{ ");
635         for (size_t i = 0; i < len; i++) {
636             result.appendFormat("0x%02x ", array[i]);
637         }
638         result += "}";
639         return result;
640     }
641 
stringMapToString(KeyedVector<String8,String8> map) const642     String8 MockDrmPlugin::stringMapToString(KeyedVector<String8, String8> map) const
643     {
644         String8 result("{ ");
645         for (size_t i = 0; i < map.size(); i++) {
646             result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "",
647                                 map.keyAt(i).string(), map.valueAt(i).string());
648         }
649         return result + " }";
650     }
651 
operator <(Vector<uint8_t> const & lhs,Vector<uint8_t> const & rhs)652     bool operator<(Vector<uint8_t> const &lhs, Vector<uint8_t> const &rhs) {
653         return lhs.size() < rhs.size() || (memcmp(lhs.array(), rhs.array(), lhs.size()) < 0);
654     }
655 
656     //
657     // Crypto Plugin
658     //
659 
requiresSecureDecoderComponent(const char * mime) const660     bool MockCryptoPlugin::requiresSecureDecoderComponent(const char *mime) const
661     {
662         ALOGD("MockCryptoPlugin::requiresSecureDecoderComponent(mime=%s)", mime);
663         return false;
664     }
665 
666     ssize_t
decrypt(bool secure,const uint8_t key[16],const uint8_t iv[16],Mode mode,const void * srcPtr,const SubSample * subSamples,size_t numSubSamples,void * dstPtr,AString * errorDetailMsg)667     MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16],
668                               Mode mode, const void *srcPtr, const SubSample *subSamples,
669                               size_t numSubSamples, void *dstPtr, AString *errorDetailMsg)
670     {
671         ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, "
672               "subSamples=%s, dst=%p)",
673               (int)secure,
674               arrayToString(key, sizeof(key)).string(),
675               arrayToString(iv, sizeof(iv)).string(),
676               (int)mode, srcPtr,
677               subSamplesToString(subSamples, numSubSamples).string(),
678               dstPtr);
679         return OK;
680     }
681 
682     // Conversion utilities
arrayToString(uint8_t const * array,size_t len) const683     String8 MockCryptoPlugin::arrayToString(uint8_t const *array, size_t len) const
684     {
685         String8 result("{ ");
686         for (size_t i = 0; i < len; i++) {
687             result.appendFormat("0x%02x ", array[i]);
688         }
689         result += "}";
690         return result;
691     }
692 
subSamplesToString(SubSample const * subSamples,size_t numSubSamples) const693     String8 MockCryptoPlugin::subSamplesToString(SubSample const *subSamples,
694                                                  size_t numSubSamples) const
695     {
696         String8 result;
697         for (size_t i = 0; i < numSubSamples; i++) {
698             result.appendFormat("[%d] {clear:%d, encrypted:%d} ", i,
699                                 subSamples[i].mNumBytesOfClearData,
700                                 subSamples[i].mNumBytesOfEncryptedData);
701         }
702         return result;
703     }
704 
705 };
706