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 29 DrmFactory *createDrmFactory() 30 { 31 return new MockDrmFactory(); 32 } 33 34 // Shared library entry point 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 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