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