Home | History | Annotate | Download | only in mock
      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 
     27 android::CasFactory* createCasFactory() {
     28     return new android::MockCasFactory();
     29 }
     30 
     31 android::DescramblerFactory* createDescramblerFactory() {
     32     return new android::MockDescramblerFactory();
     33 }
     34 
     35 namespace android {
     36 
     37 static const int32_t sMockId = 0xFFFF;
     38 
     39 bool MockCasFactory::isSystemIdSupported(int32_t CA_system_id) const {
     40     return CA_system_id == sMockId;
     41 }
     42 
     43 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 
     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 
     65 bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const {
     66     return CA_system_id == sMockId;
     67 }
     68 
     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 
     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 
     92 MockCasPlugin::MockCasPlugin() {
     93     ALOGV("CTOR");
     94 }
     95 
     96 MockCasPlugin::~MockCasPlugin() {
     97     ALOGV("DTOR");
     98     MockSessionLibrary::get()->destroyPlugin(this);
     99 }
    100 
    101 status_t MockCasPlugin::setPrivateData(const CasData &data) {
    102     ALOGV("setPrivateData");
    103     return OK;
    104 }
    105 
    106 status_t MockCasPlugin::openSession(CasSessionId* sessionId) {
    107     ALOGV("openSession");
    108     return MockSessionLibrary::get()->addSession(this, sessionId);
    109 }
    110 
    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 
    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 
    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 
    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 
    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 
    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 
    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 /////////////////////////////////////////////////////////////////
    189 bool MockDescramblerPlugin::requiresSecureDecoderComponent(
    190         const char *mime) const {
    191     ALOGV("MockDescramblerPlugin::requiresSecureDecoderComponent"
    192             "(mime=%s)", mime);
    193     return false;
    194 }
    195 
    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 
    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
    230 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 
    241 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