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