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 
HDCP(bool createEncryptionModule)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 
~HDCP()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 
setObserver(const sp<IHDCPObserver> & observer)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 
initAsync(const char * host,unsigned port)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 
shutdownAsync()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 
getCaps()103 uint32_t HDCP::getCaps() {
104     Mutex::Autolock autoLock(mLock);
105 
106     if (mHDCPModule == NULL) {
107         return NO_INIT;
108     }
109 
110     return mHDCPModule->getCaps();
111 }
112 
encrypt(const void * inData,size_t size,uint32_t streamCTR,uint64_t * outInputCTR,void * outData)113 status_t HDCP::encrypt(
114         const void *inData, size_t size, uint32_t streamCTR,
115         uint64_t *outInputCTR, void *outData) {
116     Mutex::Autolock autoLock(mLock);
117 
118     CHECK(mIsEncryptionModule);
119 
120     if (mHDCPModule == NULL) {
121         *outInputCTR = 0;
122 
123         return NO_INIT;
124     }
125 
126     return mHDCPModule->encrypt(inData, size, streamCTR, outInputCTR, outData);
127 }
128 
encryptNative(const sp<GraphicBuffer> & graphicBuffer,size_t offset,size_t size,uint32_t streamCTR,uint64_t * outInputCTR,void * outData)129 status_t HDCP::encryptNative(
130         const sp<GraphicBuffer> &graphicBuffer,
131         size_t offset, size_t size, uint32_t streamCTR,
132         uint64_t *outInputCTR, void *outData) {
133     Mutex::Autolock autoLock(mLock);
134 
135     CHECK(mIsEncryptionModule);
136 
137     if (mHDCPModule == NULL) {
138         *outInputCTR = 0;
139 
140         return NO_INIT;
141     }
142 
143     return mHDCPModule->encryptNative(graphicBuffer->handle,
144                     offset, size, streamCTR, outInputCTR, outData);
145 }
146 
decrypt(const void * inData,size_t size,uint32_t streamCTR,uint64_t outInputCTR,void * outData)147 status_t HDCP::decrypt(
148         const void *inData, size_t size,
149         uint32_t streamCTR, uint64_t outInputCTR, void *outData) {
150     Mutex::Autolock autoLock(mLock);
151 
152     CHECK(!mIsEncryptionModule);
153 
154     if (mHDCPModule == NULL) {
155         return NO_INIT;
156     }
157 
158     return mHDCPModule->decrypt(inData, size, streamCTR, outInputCTR, outData);
159 }
160 
161 // static
ObserveWrapper(void * me,int msg,int ext1,int ext2)162 void HDCP::ObserveWrapper(void *me, int msg, int ext1, int ext2) {
163     static_cast<HDCP *>(me)->observe(msg, ext1, ext2);
164 }
165 
observe(int msg,int ext1,int ext2)166 void HDCP::observe(int msg, int ext1, int ext2) {
167     Mutex::Autolock autoLock(mLock);
168 
169     if (mObserver != NULL) {
170         mObserver->notify(msg, ext1, ext2, NULL /* obj */);
171     }
172 }
173 
174 }  // namespace android
175 
176