IDrm.cpp revision 441a78d5e224e0d67f9b52fa9adc795c6944159b
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 "IDrm" 19#include <utils/Log.h> 20 21#include <binder/Parcel.h> 22#include <media/IDrm.h> 23#include <media/stagefright/MediaErrors.h> 24#include <media/stagefright/foundation/ADebug.h> 25#include <media/stagefright/foundation/AString.h> 26 27namespace android { 28 29enum { 30 INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION, 31 IS_CRYPTO_SUPPORTED, 32 CREATE_PLUGIN, 33 DESTROY_PLUGIN, 34 OPEN_SESSION, 35 CLOSE_SESSION, 36 GET_LICENSE_REQUEST, 37 PROVIDE_LICENSE_RESPONSE, 38 REMOVE_LICENSE, 39 QUERY_LICENSE_STATUS, 40 GET_PROVISION_REQUEST, 41 PROVIDE_PROVISION_RESPONSE, 42 GET_SECURE_STOPS, 43 RELEASE_SECURE_STOPS, 44 GET_PROPERTY_STRING, 45 GET_PROPERTY_BYTE_ARRAY, 46 SET_PROPERTY_STRING, 47 SET_PROPERTY_BYTE_ARRAY 48}; 49 50struct BpDrm : public BpInterface<IDrm> { 51 BpDrm(const sp<IBinder> &impl) 52 : BpInterface<IDrm>(impl) { 53 } 54 55 virtual status_t initCheck() const { 56 Parcel data, reply; 57 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 58 remote()->transact(INIT_CHECK, data, &reply); 59 60 return reply.readInt32(); 61 } 62 63 virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) { 64 Parcel data, reply; 65 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 66 data.write(uuid, 16); 67 remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply); 68 69 return reply.readInt32() != 0; 70 } 71 72 virtual status_t createPlugin(const uint8_t uuid[16]) { 73 Parcel data, reply; 74 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 75 data.write(uuid, 16); 76 77 remote()->transact(CREATE_PLUGIN, data, &reply); 78 79 return reply.readInt32(); 80 } 81 82 virtual status_t destroyPlugin() { 83 Parcel data, reply; 84 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 85 remote()->transact(DESTROY_PLUGIN, data, &reply); 86 87 return reply.readInt32(); 88 } 89 90 virtual status_t openSession(Vector<uint8_t> &sessionId) { 91 Parcel data, reply; 92 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 93 94 remote()->transact(OPEN_SESSION, data, &reply); 95 uint32_t size = reply.readInt32(); 96 sessionId.insertAt((size_t)0, size); 97 reply.read(sessionId.editArray(), size); 98 99 return reply.readInt32(); 100 } 101 102 virtual status_t closeSession(Vector<uint8_t> const &sessionId) { 103 Parcel data, reply; 104 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 105 106 data.writeInt32(sessionId.size()); 107 data.write(sessionId.array(), sessionId.size()); 108 remote()->transact(CLOSE_SESSION, data, &reply); 109 110 return reply.readInt32(); 111 } 112 113 virtual status_t 114 getLicenseRequest(Vector<uint8_t> const &sessionId, 115 Vector<uint8_t> const &initData, 116 String8 const &mimeType, DrmPlugin::LicenseType licenseType, 117 KeyedVector<String8, String8> const &optionalParameters, 118 Vector<uint8_t> &request, String8 &defaultUrl) { 119 Parcel data, reply; 120 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 121 122 data.writeInt32(sessionId.size()); 123 data.write(sessionId.array(), sessionId.size()); 124 125 data.writeInt32(initData.size()); 126 data.write(initData.array(), initData.size()); 127 128 data.writeString8(mimeType); 129 data.writeInt32((uint32_t)licenseType); 130 131 data.writeInt32(optionalParameters.size()); 132 for (size_t i = 0; i < optionalParameters.size(); ++i) { 133 data.writeString8(optionalParameters.keyAt(i)); 134 data.writeString8(optionalParameters.valueAt(i)); 135 } 136 remote()->transact(GET_LICENSE_REQUEST, data, &reply); 137 138 uint32_t len = reply.readInt32(); 139 request.insertAt((size_t)0, len); 140 reply.read(request.editArray(), len); 141 defaultUrl = reply.readString8(); 142 143 return reply.readInt32(); 144 } 145 146 virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId, 147 Vector<uint8_t> const &response) { 148 Parcel data, reply; 149 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 150 151 data.writeInt32(sessionId.size()); 152 data.write(sessionId.array(), sessionId.size()); 153 data.writeInt32(response.size()); 154 data.write(response.array(), response.size()); 155 remote()->transact(PROVIDE_LICENSE_RESPONSE, data, &reply); 156 157 return reply.readInt32(); 158 } 159 160 virtual status_t removeLicense(Vector<uint8_t> const &sessionId) { 161 Parcel data, reply; 162 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 163 164 data.writeInt32(sessionId.size()); 165 data.write(sessionId.array(), sessionId.size()); 166 remote()->transact(REMOVE_LICENSE, data, &reply); 167 168 return reply.readInt32(); 169 } 170 171 virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId, 172 KeyedVector<String8, String8> &infoMap) const { 173 Parcel data, reply; 174 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 175 176 data.writeInt32(sessionId.size()); 177 data.write(sessionId.array(), sessionId.size()); 178 179 remote()->transact(QUERY_LICENSE_STATUS, data, &reply); 180 181 infoMap.clear(); 182 size_t count = reply.readInt32(); 183 for (size_t i = 0; i < count; i++) { 184 String8 key = reply.readString8(); 185 String8 value = reply.readString8(); 186 infoMap.add(key, value); 187 } 188 return reply.readInt32(); 189 } 190 191 virtual status_t getProvisionRequest(Vector<uint8_t> &request, 192 String8 &defaultUrl) { 193 Parcel data, reply; 194 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 195 196 remote()->transact(GET_PROVISION_REQUEST, data, &reply); 197 198 uint32_t len = reply.readInt32(); 199 request.insertAt((size_t)0, len); 200 reply.read(request.editArray(), len); 201 defaultUrl = reply.readString8(); 202 203 return reply.readInt32(); 204 } 205 206 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) { 207 Parcel data, reply; 208 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 209 210 data.writeInt32(response.size()); 211 data.write(response.array(), response.size()); 212 remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply); 213 214 return reply.readInt32(); 215 } 216 217 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) { 218 Parcel data, reply; 219 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 220 221 remote()->transact(GET_SECURE_STOPS, data, &reply); 222 223 secureStops.clear(); 224 uint32_t count = reply.readInt32(); 225 for (size_t i = 0; i < count; i++) { 226 Vector<uint8_t> secureStop; 227 uint32_t len = reply.readInt32(); 228 secureStop.insertAt((size_t)0, len); 229 reply.read(secureStop.editArray(), len); 230 secureStops.push_back(secureStop); 231 } 232 return reply.readInt32(); 233 } 234 235 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) { 236 Parcel data, reply; 237 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 238 239 data.writeInt32(ssRelease.size()); 240 data.write(ssRelease.array(), ssRelease.size()); 241 remote()->transact(RELEASE_SECURE_STOPS, data, &reply); 242 243 return reply.readInt32(); 244 } 245 246 virtual status_t getPropertyString(String8 const &name, String8 &value) const { 247 Parcel data, reply; 248 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 249 250 data.writeString8(name); 251 remote()->transact(GET_PROPERTY_STRING, data, &reply); 252 253 value = reply.readString8(); 254 return reply.readInt32(); 255 } 256 257 virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const { 258 Parcel data, reply; 259 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 260 261 data.writeString8(name); 262 remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply); 263 264 uint32_t len = reply.readInt32(); 265 value.insertAt((size_t)0, len); 266 reply.read(value.editArray(), len); 267 268 return reply.readInt32(); 269 } 270 271 virtual status_t setPropertyString(String8 const &name, String8 const &value) const { 272 Parcel data, reply; 273 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 274 275 data.writeString8(name); 276 data.writeString8(value); 277 remote()->transact(SET_PROPERTY_STRING, data, &reply); 278 279 return reply.readInt32(); 280 } 281 282 virtual status_t setPropertyByteArray(String8 const &name, 283 Vector<uint8_t> const &value) const { 284 Parcel data, reply; 285 data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); 286 287 data.writeString8(name); 288 data.writeInt32(value.size()); 289 data.write(value.array(), value.size()); 290 remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply); 291 292 return reply.readInt32(); 293 } 294 295 296private: 297 DISALLOW_EVIL_CONSTRUCTORS(BpDrm); 298}; 299 300IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm"); 301 302//////////////////////////////////////////////////////////////////////////////// 303 304status_t BnDrm::onTransact( 305 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 306 switch (code) { 307 case INIT_CHECK: 308 { 309 CHECK_INTERFACE(IDrm, data, reply); 310 reply->writeInt32(initCheck()); 311 return OK; 312 } 313 314 case IS_CRYPTO_SUPPORTED: 315 { 316 CHECK_INTERFACE(IDrm, data, reply); 317 uint8_t uuid[16]; 318 data.read(uuid, sizeof(uuid)); 319 reply->writeInt32(isCryptoSchemeSupported(uuid)); 320 return OK; 321 } 322 323 case CREATE_PLUGIN: 324 { 325 CHECK_INTERFACE(IDrm, data, reply); 326 uint8_t uuid[16]; 327 data.read(uuid, sizeof(uuid)); 328 reply->writeInt32(createPlugin(uuid)); 329 return OK; 330 } 331 332 case DESTROY_PLUGIN: 333 { 334 CHECK_INTERFACE(IDrm, data, reply); 335 reply->writeInt32(destroyPlugin()); 336 return OK; 337 } 338 339 case OPEN_SESSION: 340 { 341 CHECK_INTERFACE(IDrm, data, reply); 342 Vector<uint8_t> sessionId; 343 status_t result = openSession(sessionId); 344 reply->writeInt32(sessionId.size()); 345 reply->write(sessionId.array(), sessionId.size()); 346 reply->writeInt32(result); 347 return OK; 348 } 349 350 case CLOSE_SESSION: 351 { 352 CHECK_INTERFACE(IDrm, data, reply); 353 Vector<uint8_t> sessionId; 354 uint32_t size = data.readInt32(); 355 sessionId.insertAt((size_t)0, size); 356 data.read(sessionId.editArray(), size); 357 reply->writeInt32(closeSession(sessionId)); 358 return OK; 359 } 360 361 case GET_LICENSE_REQUEST: 362 { 363 CHECK_INTERFACE(IDrm, data, reply); 364 Vector<uint8_t> sessionId; 365 uint32_t size = data.readInt32(); 366 sessionId.insertAt((size_t)0, size); 367 data.read(sessionId.editArray(), size); 368 369 Vector<uint8_t> initData; 370 size = data.readInt32(); 371 initData.insertAt((size_t)0, size); 372 data.read(initData.editArray(), size); 373 374 String8 mimeType = data.readString8(); 375 DrmPlugin::LicenseType licenseType = (DrmPlugin::LicenseType)data.readInt32(); 376 377 KeyedVector<String8, String8> optionalParameters; 378 uint32_t count = data.readInt32(); 379 for (size_t i = 0; i < count; ++i) { 380 String8 key, value; 381 key = data.readString8(); 382 value = data.readString8(); 383 optionalParameters.add(key, value); 384 } 385 386 Vector<uint8_t> request; 387 String8 defaultUrl; 388 389 status_t result = getLicenseRequest(sessionId, initData, 390 mimeType, licenseType, 391 optionalParameters, 392 request, defaultUrl); 393 reply->writeInt32(request.size()); 394 reply->write(request.array(), request.size()); 395 reply->writeString8(defaultUrl); 396 reply->writeInt32(result); 397 return OK; 398 } 399 400 case PROVIDE_LICENSE_RESPONSE: 401 { 402 CHECK_INTERFACE(IDrm, data, reply); 403 Vector<uint8_t> sessionId; 404 uint32_t size = data.readInt32(); 405 sessionId.insertAt((size_t)0, size); 406 data.read(sessionId.editArray(), size); 407 Vector<uint8_t> response; 408 size = data.readInt32(); 409 response.insertAt((size_t)0, size); 410 data.read(response.editArray(), size); 411 412 reply->writeInt32(provideLicenseResponse(sessionId, response)); 413 return OK; 414 } 415 416 case REMOVE_LICENSE: 417 { 418 CHECK_INTERFACE(IDrm, data, reply); 419 Vector<uint8_t> sessionId; 420 uint32_t size = data.readInt32(); 421 sessionId.insertAt((size_t)0, size); 422 data.read(sessionId.editArray(), size); 423 reply->writeInt32(removeLicense(sessionId)); 424 return OK; 425 } 426 427 case QUERY_LICENSE_STATUS: 428 { 429 CHECK_INTERFACE(IDrm, data, reply); 430 Vector<uint8_t> sessionId; 431 uint32_t size = data.readInt32(); 432 sessionId.insertAt((size_t)0, size); 433 data.read(sessionId.editArray(), size); 434 KeyedVector<String8, String8> infoMap; 435 436 status_t result = queryLicenseStatus(sessionId, infoMap); 437 438 size_t count = infoMap.size(); 439 reply->writeInt32(count); 440 for (size_t i = 0; i < count; ++i) { 441 reply->writeString8(infoMap.keyAt(i)); 442 reply->writeString8(infoMap.valueAt(i)); 443 } 444 reply->writeInt32(result); 445 return OK; 446 } 447 448 case GET_PROVISION_REQUEST: 449 { 450 CHECK_INTERFACE(IDrm, data, reply); 451 Vector<uint8_t> request; 452 String8 defaultUrl; 453 status_t result = getProvisionRequest(request, defaultUrl); 454 reply->writeInt32(request.size()); 455 reply->write(request.array(), request.size()); 456 reply->writeString8(defaultUrl); 457 reply->writeInt32(result); 458 return OK; 459 } 460 461 case PROVIDE_PROVISION_RESPONSE: 462 { 463 CHECK_INTERFACE(IDrm, data, reply); 464 Vector<uint8_t> response; 465 uint32_t size = data.readInt32(); 466 response.insertAt((size_t)0, size); 467 data.read(response.editArray(), size); 468 reply->writeInt32(provideProvisionResponse(response)); 469 470 return OK; 471 } 472 473 case GET_SECURE_STOPS: 474 { 475 CHECK_INTERFACE(IDrm, data, reply); 476 List<Vector<uint8_t> > secureStops; 477 status_t result = getSecureStops(secureStops); 478 size_t count = secureStops.size(); 479 reply->writeInt32(count); 480 List<Vector<uint8_t> >::iterator iter = secureStops.begin(); 481 while(iter != secureStops.end()) { 482 size_t size = iter->size(); 483 reply->writeInt32(size); 484 reply->write(iter->array(), iter->size()); 485 } 486 reply->writeInt32(result); 487 return OK; 488 } 489 490 case RELEASE_SECURE_STOPS: 491 { 492 CHECK_INTERFACE(IDrm, data, reply); 493 Vector<uint8_t> ssRelease; 494 uint32_t size = data.readInt32(); 495 ssRelease.insertAt((size_t)0, size); 496 data.read(ssRelease.editArray(), size); 497 reply->writeInt32(releaseSecureStops(ssRelease)); 498 return OK; 499 } 500 501 case GET_PROPERTY_STRING: 502 { 503 CHECK_INTERFACE(IDrm, data, reply); 504 String8 name = data.readString8(); 505 String8 value; 506 status_t result = getPropertyString(name, value); 507 reply->writeString8(value); 508 reply->writeInt32(result); 509 return OK; 510 } 511 512 case GET_PROPERTY_BYTE_ARRAY: 513 { 514 CHECK_INTERFACE(IDrm, data, reply); 515 String8 name = data.readString8(); 516 Vector<uint8_t> value; 517 status_t result = getPropertyByteArray(name, value); 518 reply->writeInt32(value.size()); 519 reply->write(value.array(), value.size()); 520 reply->writeInt32(result); 521 return OK; 522 } 523 524 case SET_PROPERTY_STRING: 525 { 526 CHECK_INTERFACE(IDrm, data, reply); 527 String8 name = data.readString8(); 528 String8 value = data.readString8(); 529 reply->writeInt32(setPropertyString(name, value)); 530 return OK; 531 } 532 533 case SET_PROPERTY_BYTE_ARRAY: 534 { 535 CHECK_INTERFACE(IDrm, data, reply); 536 String8 name = data.readString8(); 537 Vector<uint8_t> value; 538 size_t count = data.readInt32(); 539 value.insertAt((size_t)0, count); 540 data.read(value.editArray(), count); 541 reply->writeInt32(setPropertyByteArray(name, value)); 542 return OK; 543 } 544 545 default: 546 return BBinder::onTransact(code, data, reply, flags); 547 } 548} 549 550} // namespace android 551 552