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(mock_uuid))); 49 } 50 51 bool MockDrmFactory::isContentTypeSupported(const String8 &mimeType) 52 { 53 if (mimeType != "video/mp4") { 54 return false; 55 } 56 return true; 57 } 58 59 status_t MockDrmFactory::createDrmPlugin(const uint8_t uuid[16], DrmPlugin **plugin) 60 { 61 *plugin = new MockDrmPlugin(); 62 return OK; 63 } 64 65 // MockCryptoFactory 66 bool MockCryptoFactory::isCryptoSchemeSupported(const uint8_t uuid[16]) const 67 { 68 return (!memcmp(uuid, mock_uuid, sizeof(mock_uuid))); 69 } 70 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 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 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 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 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 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 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 240 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 257 status_t MockDrmPlugin::getProvisionRequest(String8 const &certType, 258 String8 const &certAuthority, 259 Vector<uint8_t> &request, 260 String8 &defaultUrl) 261 { 262 Mutex::Autolock lock(mLock); 263 ALOGD("MockDrmPlugin::getProvisionRequest()"); 264 265 // Properties used in mock test, set by cts test app returned from mock plugin 266 // byte[] mock-request -> request 267 // string mock-default-url -> defaultUrl 268 269 ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-request")); 270 if (index < 0) { 271 ALOGD("Missing 'mock-request' parameter for mock"); 272 return BAD_VALUE; 273 } else { 274 request = mByteArrayProperties.valueAt(index); 275 } 276 277 index = mStringProperties.indexOfKey(String8("mock-defaultUrl")); 278 if (index < 0) { 279 ALOGD("Missing 'mock-defaultUrl' parameter for mock"); 280 return BAD_VALUE; 281 } else { 282 defaultUrl = mStringProperties.valueAt(index); 283 } 284 return OK; 285 } 286 287 status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response, 288 Vector<uint8_t> &certificate, 289 Vector<uint8_t> &wrappedKey) 290 { 291 Mutex::Autolock lock(mLock); 292 ALOGD("MockDrmPlugin::provideProvisionResponse(%s)", 293 vectorToString(response).string()); 294 295 // Properties used in mock test, set by mock plugin and verifed cts test app 296 // byte[] response -> mock-response 297 298 mByteArrayProperties.add(String8("mock-response"), response); 299 return OK; 300 } 301 302 status_t MockDrmPlugin::unprovisionDevice() 303 { 304 ALOGD("MockDrmPlugin::unprovisionDevice()"); 305 return OK; 306 } 307 308 status_t MockDrmPlugin::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) 309 { 310 Mutex::Autolock lock(mLock); 311 ALOGD("MockDrmPlugin::getSecureStop()"); 312 313 // Properties used in mock test, set by cts test app returned from mock plugin 314 // byte[] mock-secure-stop -> first secure stop in list 315 316 ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop")); 317 if (index < 0) { 318 ALOGD("Missing 'mock-secure-stop' parameter for mock"); 319 return BAD_VALUE; 320 } else { 321 secureStop = mByteArrayProperties.valueAt(index); 322 } 323 return OK; 324 } 325 326 status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops) 327 { 328 Mutex::Autolock lock(mLock); 329 ALOGD("MockDrmPlugin::getSecureStops()"); 330 331 // Properties used in mock test, set by cts test app returned from mock plugin 332 // byte[] mock-secure-stop1 -> first secure stop in list 333 // byte[] mock-secure-stop2 -> second secure stop in list 334 335 Vector<uint8_t> ss1, ss2; 336 ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop1")); 337 if (index < 0) { 338 ALOGD("Missing 'mock-secure-stop1' parameter for mock"); 339 return BAD_VALUE; 340 } else { 341 ss1 = mByteArrayProperties.valueAt(index); 342 } 343 344 index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop2")); 345 if (index < 0) { 346 ALOGD("Missing 'mock-secure-stop2' parameter for mock"); 347 return BAD_VALUE; 348 } else { 349 ss2 = mByteArrayProperties.valueAt(index); 350 } 351 352 secureStops.push_back(ss1); 353 secureStops.push_back(ss2); 354 return OK; 355 } 356 357 status_t MockDrmPlugin::releaseSecureStops(Vector<uint8_t> const &ssRelease) 358 { 359 Mutex::Autolock lock(mLock); 360 ALOGD("MockDrmPlugin::releaseSecureStops(%s)", 361 vectorToString(ssRelease).string()); 362 363 // Properties used in mock test, set by mock plugin and verifed cts test app 364 // byte[] secure-stop-release -> mock-ssrelease 365 mByteArrayProperties.add(String8("mock-ssrelease"), ssRelease); 366 367 return OK; 368 } 369 370 status_t MockDrmPlugin::releaseAllSecureStops() 371 { 372 Mutex::Autolock lock(mLock); 373 ALOGD("MockDrmPlugin::releaseAllSecureStops()"); 374 return OK; 375 } 376 377 status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const 378 { 379 ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string()); 380 ssize_t index = mStringProperties.indexOfKey(name); 381 if (index < 0) { 382 ALOGD("no property for '%s'", name.string()); 383 return BAD_VALUE; 384 } 385 value = mStringProperties.valueAt(index); 386 return OK; 387 } 388 389 status_t MockDrmPlugin::getPropertyByteArray(String8 const &name, 390 Vector<uint8_t> &value) const 391 { 392 ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string()); 393 ssize_t index = mByteArrayProperties.indexOfKey(name); 394 if (index < 0) { 395 ALOGD("no property for '%s'", name.string()); 396 return BAD_VALUE; 397 } 398 value = mByteArrayProperties.valueAt(index); 399 return OK; 400 } 401 402 status_t MockDrmPlugin::setPropertyString(String8 const &name, 403 String8 const &value) 404 { 405 Mutex::Autolock lock(mLock); 406 ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)", 407 name.string(), value.string()); 408 409 if (name == "mock-send-event") { 410 unsigned code, extra; 411 sscanf(value.string(), "%d %d", &code, &extra); 412 DrmPlugin::EventType eventType = (DrmPlugin::EventType)code; 413 414 Vector<uint8_t> const *pSessionId = NULL; 415 ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id")); 416 if (index >= 0) { 417 pSessionId = &mByteArrayProperties[index]; 418 } 419 420 Vector<uint8_t> const *pData = NULL; 421 index = mByteArrayProperties.indexOfKey(String8("mock-event-data")); 422 if (index >= 0) { 423 pData = &mByteArrayProperties[index]; 424 } 425 ALOGD("sending event from mock drm plugin: %d %d %s %s", 426 (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}", 427 pData ? vectorToString(*pData) : "{}"); 428 429 sendEvent(eventType, extra, pSessionId, pData); 430 } else { 431 mStringProperties.add(name, value); 432 } 433 return OK; 434 } 435 436 status_t MockDrmPlugin::setPropertyByteArray(String8 const &name, 437 Vector<uint8_t> const &value) 438 { 439 Mutex::Autolock lock(mLock); 440 ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)", 441 name.string(), vectorToString(value).string()); 442 mByteArrayProperties.add(name, value); 443 return OK; 444 } 445 446 status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId, 447 String8 const &algorithm) 448 { 449 Mutex::Autolock lock(mLock); 450 451 ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)", 452 vectorToString(sessionId).string(), algorithm.string()); 453 454 ssize_t index = findSession(sessionId); 455 if (index == kNotFound) { 456 ALOGD("Invalid sessionId"); 457 return BAD_VALUE; 458 } 459 460 if (algorithm == "AES/CBC/NoPadding") { 461 return OK; 462 } 463 return BAD_VALUE; 464 } 465 466 status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId, 467 String8 const &algorithm) 468 { 469 Mutex::Autolock lock(mLock); 470 471 ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)", 472 vectorToString(sessionId).string(), algorithm.string()); 473 474 ssize_t index = findSession(sessionId); 475 if (index == kNotFound) { 476 ALOGD("Invalid sessionId"); 477 return BAD_VALUE; 478 } 479 480 if (algorithm == "HmacSHA256") { 481 return OK; 482 } 483 return BAD_VALUE; 484 } 485 486 status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId, 487 Vector<uint8_t> const &keyId, 488 Vector<uint8_t> const &input, 489 Vector<uint8_t> const &iv, 490 Vector<uint8_t> &output) 491 { 492 Mutex::Autolock lock(mLock); 493 ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)", 494 vectorToString(sessionId).string(), 495 vectorToString(keyId).string(), 496 vectorToString(input).string(), 497 vectorToString(iv).string()); 498 499 ssize_t index = findSession(sessionId); 500 if (index == kNotFound) { 501 ALOGD("Invalid sessionId"); 502 return BAD_VALUE; 503 } 504 505 // Properties used in mock test, set by mock plugin and verifed cts test app 506 // byte[] keyId -> mock-keyid 507 // byte[] input -> mock-input 508 // byte[] iv -> mock-iv 509 mByteArrayProperties.add(String8("mock-keyid"), keyId); 510 mByteArrayProperties.add(String8("mock-input"), input); 511 mByteArrayProperties.add(String8("mock-iv"), iv); 512 513 // Properties used in mock test, set by cts test app returned from mock plugin 514 // byte[] mock-output -> output 515 index = mByteArrayProperties.indexOfKey(String8("mock-output")); 516 if (index < 0) { 517 ALOGD("Missing 'mock-request' parameter for mock"); 518 return BAD_VALUE; 519 } else { 520 output = mByteArrayProperties.valueAt(index); 521 } 522 return OK; 523 } 524 525 status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId, 526 Vector<uint8_t> const &keyId, 527 Vector<uint8_t> const &input, 528 Vector<uint8_t> const &iv, 529 Vector<uint8_t> &output) 530 { 531 Mutex::Autolock lock(mLock); 532 ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)", 533 vectorToString(sessionId).string(), 534 vectorToString(keyId).string(), 535 vectorToString(input).string(), 536 vectorToString(iv).string()); 537 538 ssize_t index = findSession(sessionId); 539 if (index == kNotFound) { 540 ALOGD("Invalid sessionId"); 541 return BAD_VALUE; 542 } 543 544 // Properties used in mock test, set by mock plugin and verifed cts test app 545 // byte[] keyId -> mock-keyid 546 // byte[] input -> mock-input 547 // byte[] iv -> mock-iv 548 mByteArrayProperties.add(String8("mock-keyid"), keyId); 549 mByteArrayProperties.add(String8("mock-input"), input); 550 mByteArrayProperties.add(String8("mock-iv"), iv); 551 552 // Properties used in mock test, set by cts test app returned from mock plugin 553 // byte[] mock-output -> output 554 index = mByteArrayProperties.indexOfKey(String8("mock-output")); 555 if (index < 0) { 556 ALOGD("Missing 'mock-request' parameter for mock"); 557 return BAD_VALUE; 558 } else { 559 output = mByteArrayProperties.valueAt(index); 560 } 561 return OK; 562 } 563 564 status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId, 565 Vector<uint8_t> const &keyId, 566 Vector<uint8_t> const &message, 567 Vector<uint8_t> &signature) 568 { 569 Mutex::Autolock lock(mLock); 570 ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)", 571 vectorToString(sessionId).string(), 572 vectorToString(keyId).string(), 573 vectorToString(message).string()); 574 575 ssize_t index = findSession(sessionId); 576 if (index == kNotFound) { 577 ALOGD("Invalid sessionId"); 578 return BAD_VALUE; 579 } 580 581 // Properties used in mock test, set by mock plugin and verifed cts test app 582 // byte[] keyId -> mock-keyid 583 // byte[] message -> mock-message 584 mByteArrayProperties.add(String8("mock-keyid"), keyId); 585 mByteArrayProperties.add(String8("mock-message"), message); 586 587 // Properties used in mock test, set by cts test app returned from mock plugin 588 // byte[] mock-signature -> signature 589 index = mByteArrayProperties.indexOfKey(String8("mock-signature")); 590 if (index < 0) { 591 ALOGD("Missing 'mock-request' parameter for mock"); 592 return BAD_VALUE; 593 } else { 594 signature = mByteArrayProperties.valueAt(index); 595 } 596 return OK; 597 } 598 599 status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId, 600 Vector<uint8_t> const &keyId, 601 Vector<uint8_t> const &message, 602 Vector<uint8_t> const &signature, 603 bool &match) 604 { 605 Mutex::Autolock lock(mLock); 606 ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)", 607 vectorToString(sessionId).string(), 608 vectorToString(keyId).string(), 609 vectorToString(message).string(), 610 vectorToString(signature).string()); 611 612 ssize_t index = findSession(sessionId); 613 if (index == kNotFound) { 614 ALOGD("Invalid sessionId"); 615 return BAD_VALUE; 616 } 617 618 // Properties used in mock test, set by mock plugin and verifed cts test app 619 // byte[] keyId -> mock-keyid 620 // byte[] message -> mock-message 621 // byte[] signature -> mock-signature 622 mByteArrayProperties.add(String8("mock-keyid"), keyId); 623 mByteArrayProperties.add(String8("mock-message"), message); 624 mByteArrayProperties.add(String8("mock-signature"), signature); 625 626 // Properties used in mock test, set by cts test app returned from mock plugin 627 // String mock-match "1" or "0" -> match 628 index = mStringProperties.indexOfKey(String8("mock-match")); 629 if (index < 0) { 630 ALOGD("Missing 'mock-request' parameter for mock"); 631 return BAD_VALUE; 632 } else { 633 match = atol(mStringProperties.valueAt(index).string()); 634 } 635 return OK; 636 } 637 638 status_t MockDrmPlugin::signRSA(Vector<uint8_t> const &sessionId, 639 String8 const &algorithm, 640 Vector<uint8_t> const &message, 641 Vector<uint8_t> const &wrappedKey, 642 Vector<uint8_t> &signature) 643 { 644 Mutex::Autolock lock(mLock); 645 ALOGD("MockDrmPlugin::signRSA(sessionId=%s, algorithm=%s, keyId=%s, " 646 "message=%s, signature=%s)", 647 vectorToString(sessionId).string(), 648 algorithm.string(), 649 vectorToString(message).string(), 650 vectorToString(wrappedKey).string(), 651 vectorToString(signature).string()); 652 653 // Properties used in mock test, set by mock plugin and verifed cts test app 654 // byte[] wrappedKey -> mock-wrappedkey 655 // byte[] message -> mock-message 656 // byte[] signature -> mock-signature 657 mByteArrayProperties.add(String8("mock-sessionid"), sessionId); 658 mStringProperties.add(String8("mock-algorithm"), algorithm); 659 mByteArrayProperties.add(String8("mock-message"), message); 660 mByteArrayProperties.add(String8("mock-wrappedkey"), wrappedKey); 661 mByteArrayProperties.add(String8("mock-signature"), signature); 662 return OK; 663 } 664 665 ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const 666 { 667 ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size()); 668 for (size_t i = 0; i < mSessions.size(); ++i) { 669 if (memcmp(mSessions[i].array(), sessionId.array(), sessionId.size()) == 0) { 670 return i; 671 } 672 } 673 return kNotFound; 674 } 675 676 ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const 677 { 678 ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size()); 679 for (size_t i = 0; i < mKeySets.size(); ++i) { 680 if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) { 681 return i; 682 } 683 } 684 return kNotFound; 685 } 686 687 688 // Conversion utilities 689 String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const 690 { 691 return arrayToString(vector.array(), vector.size()); 692 } 693 694 String8 MockDrmPlugin::arrayToString(uint8_t const *array, size_t len) const 695 { 696 String8 result("{ "); 697 for (size_t i = 0; i < len; i++) { 698 result.appendFormat("0x%02x ", array[i]); 699 } 700 result += "}"; 701 return result; 702 } 703 704 String8 MockDrmPlugin::stringMapToString(KeyedVector<String8, String8> map) const 705 { 706 String8 result("{ "); 707 for (size_t i = 0; i < map.size(); i++) { 708 result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "", 709 map.keyAt(i).string(), map.valueAt(i).string()); 710 } 711 return result + " }"; 712 } 713 714 bool operator<(Vector<uint8_t> const &lhs, Vector<uint8_t> const &rhs) { 715 return lhs.size() < rhs.size() || (memcmp(lhs.array(), rhs.array(), lhs.size()) < 0); 716 } 717 718 // 719 // Crypto Plugin 720 // 721 722 bool MockCryptoPlugin::requiresSecureDecoderComponent(const char *mime) const 723 { 724 ALOGD("MockCryptoPlugin::requiresSecureDecoderComponent(mime=%s)", mime); 725 return false; 726 } 727 728 ssize_t 729 MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16], 730 Mode mode, const void *srcPtr, const SubSample *subSamples, 731 size_t numSubSamples, void *dstPtr, AString *errorDetailMsg) 732 { 733 ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, " 734 "subSamples=%s, dst=%p)", 735 (int)secure, 736 arrayToString(key, sizeof(key)).string(), 737 arrayToString(iv, sizeof(iv)).string(), 738 (int)mode, srcPtr, 739 subSamplesToString(subSamples, numSubSamples).string(), 740 dstPtr); 741 return OK; 742 } 743 744 // Conversion utilities 745 String8 MockCryptoPlugin::arrayToString(uint8_t const *array, size_t len) const 746 { 747 String8 result("{ "); 748 for (size_t i = 0; i < len; i++) { 749 result.appendFormat("0x%02x ", array[i]); 750 } 751 result += "}"; 752 return result; 753 } 754 755 String8 MockCryptoPlugin::subSamplesToString(SubSample const *subSamples, 756 size_t numSubSamples) const 757 { 758 String8 result; 759 for (size_t i = 0; i < numSubSamples; i++) { 760 result.appendFormat("[%zu] {clear:%zu, encrypted:%zu} ", i, 761 subSamples[i].mNumBytesOfClearData, 762 subSamples[i].mNumBytesOfEncryptedData); 763 } 764 return result; 765 } 766 767 }; 768