/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "HDCP" #include <utils/Log.h> #include "HDCP.h" #include <media/stagefright/foundation/ADebug.h> #include <dlfcn.h> namespace android { HDCP::HDCP(bool createEncryptionModule) : mIsEncryptionModule(createEncryptionModule), mLibHandle(NULL), mHDCPModule(NULL) { mLibHandle = dlopen("libstagefright_hdcp.so", RTLD_NOW); if (mLibHandle == NULL) { ALOGE("Unable to locate libstagefright_hdcp.so"); return; } typedef HDCPModule *(*CreateHDCPModuleFunc)( void *, HDCPModule::ObserverFunc); CreateHDCPModuleFunc createHDCPModule = mIsEncryptionModule ? (CreateHDCPModuleFunc)dlsym(mLibHandle, "createHDCPModule") : (CreateHDCPModuleFunc)dlsym( mLibHandle, "createHDCPModuleForDecryption"); if (createHDCPModule == NULL) { ALOGE("Unable to find symbol 'createHDCPModule'."); } else if ((mHDCPModule = createHDCPModule( this, &HDCP::ObserveWrapper)) == NULL) { ALOGE("createHDCPModule failed."); } } HDCP::~HDCP() { Mutex::Autolock autoLock(mLock); if (mHDCPModule != NULL) { delete mHDCPModule; mHDCPModule = NULL; } if (mLibHandle != NULL) { dlclose(mLibHandle); mLibHandle = NULL; } } status_t HDCP::setObserver(const sp<IHDCPObserver> &observer) { Mutex::Autolock autoLock(mLock); if (mHDCPModule == NULL) { return NO_INIT; } mObserver = observer; return OK; } status_t HDCP::initAsync(const char *host, unsigned port) { Mutex::Autolock autoLock(mLock); if (mHDCPModule == NULL) { return NO_INIT; } return mHDCPModule->initAsync(host, port); } status_t HDCP::shutdownAsync() { Mutex::Autolock autoLock(mLock); if (mHDCPModule == NULL) { return NO_INIT; } return mHDCPModule->shutdownAsync(); } uint32_t HDCP::getCaps() { Mutex::Autolock autoLock(mLock); if (mHDCPModule == NULL) { return NO_INIT; } return mHDCPModule->getCaps(); } status_t HDCP::encrypt( const void *inData, size_t size, uint32_t streamCTR, uint64_t *outInputCTR, void *outData) { Mutex::Autolock autoLock(mLock); CHECK(mIsEncryptionModule); if (mHDCPModule == NULL) { *outInputCTR = 0; return NO_INIT; } return mHDCPModule->encrypt(inData, size, streamCTR, outInputCTR, outData); } status_t HDCP::encryptNative( const sp<GraphicBuffer> &graphicBuffer, size_t offset, size_t size, uint32_t streamCTR, uint64_t *outInputCTR, void *outData) { Mutex::Autolock autoLock(mLock); CHECK(mIsEncryptionModule); if (mHDCPModule == NULL) { *outInputCTR = 0; return NO_INIT; } return mHDCPModule->encryptNative(graphicBuffer->handle, offset, size, streamCTR, outInputCTR, outData); } status_t HDCP::decrypt( const void *inData, size_t size, uint32_t streamCTR, uint64_t outInputCTR, void *outData) { Mutex::Autolock autoLock(mLock); CHECK(!mIsEncryptionModule); if (mHDCPModule == NULL) { return NO_INIT; } return mHDCPModule->decrypt(inData, size, streamCTR, outInputCTR, outData); } // static void HDCP::ObserveWrapper(void *me, int msg, int ext1, int ext2) { static_cast<HDCP *>(me)->observe(msg, ext1, ext2); } void HDCP::observe(int msg, int ext1, int ext2) { Mutex::Autolock autoLock(mLock); if (mObserver != NULL) { mObserver->notify(msg, ext1, ext2, NULL /* obj */); } } } // namespace android