• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 "MockCasPlugin"
19 
20 #include <media/stagefright/foundation/hexdump.h>
21 #include <media/stagefright/MediaErrors.h>
22 #include <utils/Log.h>
23 
24 #include "MockCasPlugin.h"
25 #include "MockSessionLibrary.h"
26 
createCasFactory()27 android::CasFactory* createCasFactory() {
28     return new android::MockCasFactory();
29 }
30 
createDescramblerFactory()31 android::DescramblerFactory* createDescramblerFactory() {
32     return new android::MockDescramblerFactory();
33 }
34 
35 namespace android {
36 
37 static const int32_t sMockId = 0xFFFF;
38 
isSystemIdSupported(int32_t CA_system_id) const39 bool MockCasFactory::isSystemIdSupported(int32_t CA_system_id) const {
40     return CA_system_id == sMockId;
41 }
42 
queryPlugins(std::vector<CasPluginDescriptor> * descriptors) const43 status_t MockCasFactory::queryPlugins(
44         std::vector<CasPluginDescriptor> *descriptors) const {
45     descriptors->clear();
46     descriptors->push_back({sMockId, String8("MockCAS")});
47     return OK;
48 }
49 
createPlugin(int32_t CA_system_id,uint64_t appData,CasPluginCallback callback,CasPlugin ** plugin)50 status_t MockCasFactory::createPlugin(
51         int32_t CA_system_id,
52         uint64_t appData,
53         CasPluginCallback callback,
54         CasPlugin **plugin) {
55     if (!isSystemIdSupported(CA_system_id)) {
56         return BAD_VALUE;
57     }
58 
59     *plugin = new MockCasPlugin();
60     return OK;
61 }
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 
isSystemIdSupported(int32_t CA_system_id) const65 bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const {
66     return CA_system_id == sMockId;
67 }
68 
createPlugin(int32_t CA_system_id,DescramblerPlugin ** plugin)69 status_t MockDescramblerFactory::createPlugin(
70         int32_t CA_system_id, DescramblerPlugin** plugin) {
71     if (!isSystemIdSupported(CA_system_id)) {
72         return BAD_VALUE;
73     }
74 
75     *plugin = new MockDescramblerPlugin();
76     return OK;
77 }
78 
79 ///////////////////////////////////////////////////////////////////////////////
80 
arrayToString(const std::vector<uint8_t> & array)81 static String8 arrayToString(const std::vector<uint8_t> &array) {
82     String8 result;
83     for (size_t i = 0; i < array.size(); i++) {
84         result.appendFormat("%02x ", array[i]);
85     }
86     if (result.isEmpty()) {
87         result.append("(null)");
88     }
89     return result;
90 }
91 
MockCasPlugin()92 MockCasPlugin::MockCasPlugin() {
93     ALOGV("CTOR");
94 }
95 
~MockCasPlugin()96 MockCasPlugin::~MockCasPlugin() {
97     ALOGV("DTOR");
98     MockSessionLibrary::get()->destroyPlugin(this);
99 }
100 
setPrivateData(const CasData & data)101 status_t MockCasPlugin::setPrivateData(const CasData &data) {
102     ALOGV("setPrivateData");
103     return OK;
104 }
105 
openSession(CasSessionId * sessionId)106 status_t MockCasPlugin::openSession(CasSessionId* sessionId) {
107     ALOGV("openSession");
108     return MockSessionLibrary::get()->addSession(this, sessionId);
109 }
110 
closeSession(const CasSessionId & sessionId)111 status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
112     ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).string());
113     Mutex::Autolock lock(mLock);
114 
115     sp<MockCasSession> session =
116             MockSessionLibrary::get()->findSession(sessionId);
117     if (session == NULL) {
118         return BAD_VALUE;
119     }
120 
121     MockSessionLibrary::get()->destroySession(sessionId);
122     return OK;
123 }
124 
setSessionPrivateData(const CasSessionId & sessionId,const CasData & data)125 status_t MockCasPlugin::setSessionPrivateData(
126         const CasSessionId &sessionId, const CasData &data) {
127     ALOGV("setSessionPrivateData: sessionId=%s",
128             arrayToString(sessionId).string());
129     Mutex::Autolock lock(mLock);
130 
131     sp<MockCasSession> session =
132             MockSessionLibrary::get()->findSession(sessionId);
133     if (session == NULL) {
134         return BAD_VALUE;
135     }
136     return OK;
137 }
138 
processEcm(const CasSessionId & sessionId,const CasEcm & ecm)139 status_t MockCasPlugin::processEcm(
140         const CasSessionId &sessionId, const CasEcm& ecm) {
141     ALOGV("processEcm: sessionId=%s", arrayToString(sessionId).string());
142     Mutex::Autolock lock(mLock);
143 
144     sp<MockCasSession> session =
145             MockSessionLibrary::get()->findSession(sessionId);
146     if (session == NULL) {
147         return BAD_VALUE;
148     }
149     ALOGV("ECM: size=%d", ecm.size());
150     ALOGV("ECM: data=%s", arrayToString(ecm).string());
151 
152     return OK;
153 }
154 
processEmm(const CasEmm & emm)155 status_t MockCasPlugin::processEmm(const CasEmm& emm) {
156     ALOGV("processEmm");
157     Mutex::Autolock lock(mLock);
158 
159     ALOGV("EMM: size=%d", emm.size());
160     ALOGV("EMM: data=%s", arrayToString(emm).string());
161 
162     return OK;
163 }
164 
sendEvent(int32_t event,int arg,const CasData & eventData)165 status_t MockCasPlugin::sendEvent(
166         int32_t event, int arg, const CasData &eventData) {
167     ALOGV("sendEvent: event=%d", event);
168     Mutex::Autolock lock(mLock);
169 
170     return OK;
171 }
172 
provision(const String8 & str)173 status_t MockCasPlugin::provision(const String8 &str) {
174     ALOGV("provision: provisionString=%s", str.string());
175     Mutex::Autolock lock(mLock);
176 
177     return OK;
178 }
179 
refreshEntitlements(int32_t refreshType,const CasData & refreshData)180 status_t MockCasPlugin::refreshEntitlements(
181         int32_t refreshType, const CasData &refreshData) {
182     ALOGV("refreshEntitlements: refreshData=%s", arrayToString(refreshData).string());
183     Mutex::Autolock lock(mLock);
184 
185     return OK;
186 }
187 
188 /////////////////////////////////////////////////////////////////
requiresSecureDecoderComponent(const char * mime) const189 bool MockDescramblerPlugin::requiresSecureDecoderComponent(
190         const char *mime) const {
191     ALOGV("MockDescramblerPlugin::requiresSecureDecoderComponent"
192             "(mime=%s)", mime);
193     return false;
194 }
195 
setMediaCasSession(const CasSessionId & sessionId)196 status_t MockDescramblerPlugin::setMediaCasSession(
197         const CasSessionId &sessionId) {
198     ALOGV("MockDescramblerPlugin::setMediaCasSession");
199     sp<MockCasSession> session =
200             MockSessionLibrary::get()->findSession(sessionId);
201 
202     if (session == NULL) {
203         ALOGE("MockDescramblerPlugin: session not found");
204         return ERROR_DRM_SESSION_NOT_OPENED;
205     }
206 
207     return OK;
208 }
209 
descramble(bool secure,ScramblingControl scramblingControl,size_t numSubSamples,const SubSample * subSamples,const void * srcPtr,int32_t srcOffset,void * dstPtr,int32_t dstOffset,AString * errorDetailMsg)210 ssize_t MockDescramblerPlugin::descramble(
211         bool secure,
212         ScramblingControl scramblingControl,
213         size_t numSubSamples,
214         const SubSample *subSamples,
215         const void *srcPtr,
216         int32_t srcOffset,
217         void *dstPtr,
218         int32_t dstOffset,
219         AString *errorDetailMsg) {
220     ALOGV("MockDescramblerPlugin::descramble(secure=%d, sctrl=%d,"
221           "subSamples=%s, srcPtr=%p, dstPtr=%p, srcOffset=%d, dstOffset=%d)",
222           (int)secure, (int)scramblingControl,
223           subSamplesToString(subSamples, numSubSamples).string(),
224           srcPtr, dstPtr, srcOffset, dstOffset);
225 
226     return 0;
227 }
228 
229 // Conversion utilities
arrayToString(uint8_t const * array,size_t len) const230 String8 MockDescramblerPlugin::arrayToString(
231         uint8_t const *array, size_t len) const
232 {
233     String8 result("{ ");
234     for (size_t i = 0; i < len; i++) {
235         result.appendFormat("0x%02x ", array[i]);
236     }
237     result += "}";
238     return result;
239 }
240 
subSamplesToString(SubSample const * subSamples,size_t numSubSamples) const241 String8 MockDescramblerPlugin::subSamplesToString(
242         SubSample const *subSamples, size_t numSubSamples) const
243 {
244     String8 result;
245     for (size_t i = 0; i < numSubSamples; i++) {
246         result.appendFormat("[%zu] {clear:%u, encrypted:%u} ", i,
247                             subSamples[i].mNumBytesOfClearData,
248                             subSamples[i].mNumBytesOfEncryptedData);
249     }
250     return result;
251 }
252 
253 } // namespace android
254 
255