MockCasPlugin.cpp revision 791a1a206b56be8601a6fffd2614926e67d64790
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 27android::CasFactory* createCasFactory() { 28 return new android::MockCasFactory(); 29} 30 31android::DescramblerFactory* createDescramblerFactory() { 32 return new android::MockDescramblerFactory(); 33} 34 35namespace android { 36 37static const int32_t sMockId = 0xFFFF; 38 39bool MockCasFactory::isSystemIdSupported(int32_t CA_system_id) const { 40 return CA_system_id == sMockId; 41} 42 43status_t MockCasFactory::queryPlugins( 44 std::vector<CasPluginDescriptor> *descriptors) const { 45 descriptors->clear(); 46 descriptors->push_back({sMockId, String8("MockCAS")}); 47 return OK; 48} 49 50status_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 65bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const { 66 return CA_system_id == sMockId; 67} 68 69status_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 81static 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 92MockCasPlugin::MockCasPlugin() { 93 ALOGV("CTOR"); 94} 95 96MockCasPlugin::~MockCasPlugin() { 97 ALOGV("DTOR"); 98 MockSessionLibrary::get()->destroyPlugin(this); 99} 100 101status_t MockCasPlugin::setPrivateData(const CasData &data) { 102 ALOGV("setPrivateData"); 103 return OK; 104} 105 106status_t MockCasPlugin::openSession( 107 uint16_t program_number, CasSessionId* sessionId) { 108 ALOGV("openSession: program_number=%u", program_number); 109 return MockSessionLibrary::get()->addSession( 110 this, program_number, 0, sessionId); 111} 112 113status_t MockCasPlugin::openSession( 114 uint16_t program_number, 115 uint16_t elementary_PID, 116 CasSessionId *sessionId) { 117 ALOGV("openSession: program_number=%u, elementary_PID=%u", 118 program_number, elementary_PID); 119 120 return MockSessionLibrary::get()->addSession( 121 this, program_number, elementary_PID, sessionId); 122} 123 124status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) { 125 ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).string()); 126 Mutex::Autolock lock(mLock); 127 128 sp<MockCasSession> session = 129 MockSessionLibrary::get()->findSession(sessionId); 130 if (session == NULL) { 131 return BAD_VALUE; 132 } 133 134 MockSessionLibrary::get()->destroySession(sessionId); 135 return OK; 136} 137 138status_t MockCasPlugin::setSessionPrivateData( 139 const CasSessionId &sessionId, const CasData &data) { 140 ALOGV("setSessionPrivateData: sessionId=%s", 141 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 return OK; 150} 151 152status_t MockCasPlugin::processEcm( 153 const CasSessionId &sessionId, const CasEcm& ecm) { 154 ALOGV("processEcm: sessionId=%s", arrayToString(sessionId).string()); 155 Mutex::Autolock lock(mLock); 156 157 sp<MockCasSession> session = 158 MockSessionLibrary::get()->findSession(sessionId); 159 if (session == NULL) { 160 return BAD_VALUE; 161 } 162 ALOGV("ECM: size=%d", ecm.size()); 163 ALOGV("ECM: data=%s", arrayToString(ecm).string()); 164 165 return OK; 166} 167 168status_t MockCasPlugin::processEmm(const CasEmm& emm) { 169 ALOGV("processEmm"); 170 Mutex::Autolock lock(mLock); 171 172 ALOGV("EMM: size=%d", emm.size()); 173 ALOGV("EMM: data=%s", arrayToString(emm).string()); 174 175 return OK; 176} 177 178status_t MockCasPlugin::sendEvent( 179 int32_t event, int arg, const CasData &eventData) { 180 ALOGV("sendEvent: event=%d", event); 181 Mutex::Autolock lock(mLock); 182 183 return OK; 184} 185 186status_t MockCasPlugin::provision(const String8 &str) { 187 ALOGV("provision: provisionString=%s", str.string()); 188 Mutex::Autolock lock(mLock); 189 190 return OK; 191} 192 193status_t MockCasPlugin::refreshEntitlements( 194 int32_t refreshType, const CasData &refreshData) { 195 ALOGV("refreshEntitlements: refreshData=%s", arrayToString(refreshData).string()); 196 Mutex::Autolock lock(mLock); 197 198 return OK; 199} 200 201///////////////////////////////////////////////////////////////// 202bool MockDescramblerPlugin::requiresSecureDecoderComponent( 203 const char *mime) const { 204 ALOGV("MockDescramblerPlugin::requiresSecureDecoderComponent" 205 "(mime=%s)", mime); 206 return false; 207} 208 209status_t MockDescramblerPlugin::setMediaCasSession( 210 const CasSessionId &sessionId) { 211 ALOGV("MockDescramblerPlugin::setMediaCasSession"); 212 sp<MockCasSession> session = 213 MockSessionLibrary::get()->findSession(sessionId); 214 215 if (session == NULL) { 216 ALOGE("MockDescramblerPlugin: session not found"); 217 return ERROR_DRM_SESSION_NOT_OPENED; 218 } 219 220 return OK; 221} 222 223ssize_t MockDescramblerPlugin::descramble( 224 bool secure, 225 ScramblingControl scramblingControl, 226 size_t numSubSamples, 227 const SubSample *subSamples, 228 const void *srcPtr, 229 int32_t srcOffset, 230 void *dstPtr, 231 int32_t dstOffset, 232 AString *errorDetailMsg) { 233 ALOGV("MockDescramblerPlugin::descramble(secure=%d, sctrl=%d," 234 "subSamples=%s, srcPtr=%p, dstPtr=%p, srcOffset=%d, dstOffset=%d)", 235 (int)secure, (int)scramblingControl, 236 subSamplesToString(subSamples, numSubSamples).string(), 237 srcPtr, dstPtr, srcOffset, dstOffset); 238 239 return 0; 240} 241 242// Conversion utilities 243String8 MockDescramblerPlugin::arrayToString( 244 uint8_t const *array, size_t len) const 245{ 246 String8 result("{ "); 247 for (size_t i = 0; i < len; i++) { 248 result.appendFormat("0x%02x ", array[i]); 249 } 250 result += "}"; 251 return result; 252} 253 254String8 MockDescramblerPlugin::subSamplesToString( 255 SubSample const *subSamples, size_t numSubSamples) const 256{ 257 String8 result; 258 for (size_t i = 0; i < numSubSamples; i++) { 259 result.appendFormat("[%zu] {clear:%u, encrypted:%u} ", i, 260 subSamples[i].mNumBytesOfClearData, 261 subSamples[i].mNumBytesOfEncryptedData); 262 } 263 return result; 264} 265 266} // namespace android 267 268