11b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber/* 21b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * Copyright (C) 2012 The Android Open Source Project 31b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * 41b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 51b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * you may not use this file except in compliance with the License. 61b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * You may obtain a copy of the License at 71b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * 81b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 91b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * 101b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * Unless required by applicable law or agreed to in writing, software 111b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 121b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * See the License for the specific language governing permissions and 141b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber * limitations under the License. 151b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber */ 161b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 171b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber//#define LOG_NDEBUG 0 181b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#define LOG_TAG "HDCP" 191b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <utils/Log.h> 201b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 211b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include "HDCP.h" 221b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 231b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <media/stagefright/foundation/ADebug.h> 241b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 251b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber#include <dlfcn.h> 261b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 271b19c9d120869c3182373a9b06a1ed98898df882Andreas Hubernamespace android { 281b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 29a6a88d9c445e261972c2433254e0a996336e78a4Andreas HuberHDCP::HDCP(bool createEncryptionModule) 30a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber : mIsEncryptionModule(createEncryptionModule), 31a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber mLibHandle(NULL), 321b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber mHDCPModule(NULL) { 331b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber mLibHandle = dlopen("libstagefright_hdcp.so", RTLD_NOW); 341b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 351b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mLibHandle == NULL) { 361b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber ALOGE("Unable to locate libstagefright_hdcp.so"); 371b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return; 381b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 391b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 40efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber typedef HDCPModule *(*CreateHDCPModuleFunc)( 41efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber void *, HDCPModule::ObserverFunc); 42efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber 431b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber CreateHDCPModuleFunc createHDCPModule = 44a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber mIsEncryptionModule 45a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber ? (CreateHDCPModuleFunc)dlsym(mLibHandle, "createHDCPModule") 46a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber : (CreateHDCPModuleFunc)dlsym( 47a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber mLibHandle, "createHDCPModuleForDecryption"); 481b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 491b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (createHDCPModule == NULL) { 501b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber ALOGE("Unable to find symbol 'createHDCPModule'."); 51efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber } else if ((mHDCPModule = createHDCPModule( 52efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber this, &HDCP::ObserveWrapper)) == NULL) { 531b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber ALOGE("createHDCPModule failed."); 541b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 551b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 561b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 571b19c9d120869c3182373a9b06a1ed98898df882Andreas HuberHDCP::~HDCP() { 58ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber Mutex::Autolock autoLock(mLock); 59ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 601b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mHDCPModule != NULL) { 611b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber delete mHDCPModule; 621b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber mHDCPModule = NULL; 631b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 641b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 651b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mLibHandle != NULL) { 661b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber dlclose(mLibHandle); 671b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber mLibHandle = NULL; 681b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 691b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 701b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 711b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstatus_t HDCP::setObserver(const sp<IHDCPObserver> &observer) { 72ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber Mutex::Autolock autoLock(mLock); 73ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 741b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mHDCPModule == NULL) { 751b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return NO_INIT; 761b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 771b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 781b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber mObserver = observer; 791b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 801b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return OK; 811b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 821b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 831b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstatus_t HDCP::initAsync(const char *host, unsigned port) { 84ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber Mutex::Autolock autoLock(mLock); 85ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 861b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mHDCPModule == NULL) { 871b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return NO_INIT; 881b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 891b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 901b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return mHDCPModule->initAsync(host, port); 911b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 921b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 931b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstatus_t HDCP::shutdownAsync() { 94ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber Mutex::Autolock autoLock(mLock); 95ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 961b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mHDCPModule == NULL) { 971b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return NO_INIT; 981b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 991b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1001b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return mHDCPModule->shutdownAsync(); 1011b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 1021b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 103ec3acca4a75fc4adc076b56751124f507b419622Chong Zhanguint32_t HDCP::getCaps() { 104ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang Mutex::Autolock autoLock(mLock); 105ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang 106ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang if (mHDCPModule == NULL) { 107ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang return NO_INIT; 108ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang } 109ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang 110a664d6b45777efb8f8b7c8a391d785f6152fa8dbChong Zhang return mHDCPModule->getCaps(); 111ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang} 112ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang 1131b19c9d120869c3182373a9b06a1ed98898df882Andreas Huberstatus_t HDCP::encrypt( 1141b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber const void *inData, size_t size, uint32_t streamCTR, 1151b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber uint64_t *outInputCTR, void *outData) { 116ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber Mutex::Autolock autoLock(mLock); 117ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 118a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber CHECK(mIsEncryptionModule); 119a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber 1201b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber if (mHDCPModule == NULL) { 1211b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber *outInputCTR = 0; 1221b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1231b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return NO_INIT; 1241b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber } 1251b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 1261b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber return mHDCPModule->encrypt(inData, size, streamCTR, outInputCTR, outData); 1271b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} 1281b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 129308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangstatus_t HDCP::encryptNative( 130308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang const sp<GraphicBuffer> &graphicBuffer, 131308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang size_t offset, size_t size, uint32_t streamCTR, 132308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang uint64_t *outInputCTR, void *outData) { 133308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang Mutex::Autolock autoLock(mLock); 134308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 135308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(mIsEncryptionModule); 136308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 137308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (mHDCPModule == NULL) { 138308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang *outInputCTR = 0; 139308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 140308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang return NO_INIT; 141308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 142308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 143308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang return mHDCPModule->encryptNative(graphicBuffer->handle, 144308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang offset, size, streamCTR, outInputCTR, outData); 145308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang} 146308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 147a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huberstatus_t HDCP::decrypt( 148a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber const void *inData, size_t size, 149a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber uint32_t streamCTR, uint64_t outInputCTR, void *outData) { 150a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber Mutex::Autolock autoLock(mLock); 151a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber 152a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber CHECK(!mIsEncryptionModule); 153a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber 154a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber if (mHDCPModule == NULL) { 155a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber return NO_INIT; 156a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber } 157a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber 158a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber return mHDCPModule->decrypt(inData, size, streamCTR, outInputCTR, outData); 159a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber} 160a6a88d9c445e261972c2433254e0a996336e78a4Andreas Huber 161efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber// static 162efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Hubervoid HDCP::ObserveWrapper(void *me, int msg, int ext1, int ext2) { 163efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber static_cast<HDCP *>(me)->observe(msg, ext1, ext2); 164efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber} 165efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber 166efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Hubervoid HDCP::observe(int msg, int ext1, int ext2) { 167ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber Mutex::Autolock autoLock(mLock); 168ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 169efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber if (mObserver != NULL) { 170efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber mObserver->notify(msg, ext1, ext2, NULL /* obj */); 171efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber } 172efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber} 173efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber 1741b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber} // namespace android 1751b19c9d120869c3182373a9b06a1ed98898df882Andreas Huber 176