1 /* 2 * Copyright (C) 2012 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 "HDCP" 19 #include <utils/Log.h> 20 21 #include "HDCP.h" 22 23 #include <media/stagefright/foundation/ADebug.h> 24 25 #include <dlfcn.h> 26 27 namespace android { 28 29 HDCP::HDCP(bool createEncryptionModule) 30 : mIsEncryptionModule(createEncryptionModule), 31 mLibHandle(NULL), 32 mHDCPModule(NULL) { 33 mLibHandle = dlopen("libstagefright_hdcp.so", RTLD_NOW); 34 35 if (mLibHandle == NULL) { 36 ALOGE("Unable to locate libstagefright_hdcp.so"); 37 return; 38 } 39 40 typedef HDCPModule *(*CreateHDCPModuleFunc)( 41 void *, HDCPModule::ObserverFunc); 42 43 CreateHDCPModuleFunc createHDCPModule = 44 mIsEncryptionModule 45 ? (CreateHDCPModuleFunc)dlsym(mLibHandle, "createHDCPModule") 46 : (CreateHDCPModuleFunc)dlsym( 47 mLibHandle, "createHDCPModuleForDecryption"); 48 49 if (createHDCPModule == NULL) { 50 ALOGE("Unable to find symbol 'createHDCPModule'."); 51 } else if ((mHDCPModule = createHDCPModule( 52 this, &HDCP::ObserveWrapper)) == NULL) { 53 ALOGE("createHDCPModule failed."); 54 } 55 } 56 57 HDCP::~HDCP() { 58 Mutex::Autolock autoLock(mLock); 59 60 if (mHDCPModule != NULL) { 61 delete mHDCPModule; 62 mHDCPModule = NULL; 63 } 64 65 if (mLibHandle != NULL) { 66 dlclose(mLibHandle); 67 mLibHandle = NULL; 68 } 69 } 70 71 status_t HDCP::setObserver(const sp<IHDCPObserver> &observer) { 72 Mutex::Autolock autoLock(mLock); 73 74 if (mHDCPModule == NULL) { 75 return NO_INIT; 76 } 77 78 mObserver = observer; 79 80 return OK; 81 } 82 83 status_t HDCP::initAsync(const char *host, unsigned port) { 84 Mutex::Autolock autoLock(mLock); 85 86 if (mHDCPModule == NULL) { 87 return NO_INIT; 88 } 89 90 return mHDCPModule->initAsync(host, port); 91 } 92 93 status_t HDCP::shutdownAsync() { 94 Mutex::Autolock autoLock(mLock); 95 96 if (mHDCPModule == NULL) { 97 return NO_INIT; 98 } 99 100 return mHDCPModule->shutdownAsync(); 101 } 102 103 uint32_t HDCP::getCaps() { 104 Mutex::Autolock autoLock(mLock); 105 106 if (mHDCPModule == NULL) { 107 return NO_INIT; 108 } 109 110 // TO-DO: 111 // Only support HDCP_CAPS_ENCRYPT (byte-array to byte-array) for now. 112 // use mHDCPModule->getCaps() when the HDCP libraries get updated. 113 //return mHDCPModule->getCaps(); 114 return HDCPModule::HDCP_CAPS_ENCRYPT; 115 } 116 117 status_t HDCP::encrypt( 118 const void *inData, size_t size, uint32_t streamCTR, 119 uint64_t *outInputCTR, void *outData) { 120 Mutex::Autolock autoLock(mLock); 121 122 CHECK(mIsEncryptionModule); 123 124 if (mHDCPModule == NULL) { 125 *outInputCTR = 0; 126 127 return NO_INIT; 128 } 129 130 return mHDCPModule->encrypt(inData, size, streamCTR, outInputCTR, outData); 131 } 132 133 status_t HDCP::encryptNative( 134 const sp<GraphicBuffer> &graphicBuffer, 135 size_t offset, size_t size, uint32_t streamCTR, 136 uint64_t *outInputCTR, void *outData) { 137 Mutex::Autolock autoLock(mLock); 138 139 CHECK(mIsEncryptionModule); 140 141 if (mHDCPModule == NULL) { 142 *outInputCTR = 0; 143 144 return NO_INIT; 145 } 146 147 return mHDCPModule->encryptNative(graphicBuffer->handle, 148 offset, size, streamCTR, outInputCTR, outData); 149 } 150 151 status_t HDCP::decrypt( 152 const void *inData, size_t size, 153 uint32_t streamCTR, uint64_t outInputCTR, void *outData) { 154 Mutex::Autolock autoLock(mLock); 155 156 CHECK(!mIsEncryptionModule); 157 158 if (mHDCPModule == NULL) { 159 return NO_INIT; 160 } 161 162 return mHDCPModule->decrypt(inData, size, streamCTR, outInputCTR, outData); 163 } 164 165 // static 166 void HDCP::ObserveWrapper(void *me, int msg, int ext1, int ext2) { 167 static_cast<HDCP *>(me)->observe(msg, ext1, ext2); 168 } 169 170 void HDCP::observe(int msg, int ext1, int ext2) { 171 Mutex::Autolock autoLock(mLock); 172 173 if (mObserver != NULL) { 174 mObserver->notify(msg, ext1, ext2, NULL /* obj */); 175 } 176 } 177 178 } // namespace android 179 180