Home | History | Annotate | Download | only in functional
      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_TAG "mediacas_hidl_hal_test"
     18 
     19 #include <VtsHalHidlTargetTestBase.h>
     20 #include <VtsHalHidlTargetTestEnvBase.h>
     21 #include <android-base/logging.h>
     22 #include <android/hardware/cas/1.0/ICas.h>
     23 #include <android/hardware/cas/1.0/ICasListener.h>
     24 #include <android/hardware/cas/1.0/IDescramblerBase.h>
     25 #include <android/hardware/cas/1.0/IMediaCasService.h>
     26 #include <android/hardware/cas/1.0/types.h>
     27 #include <android/hardware/cas/native/1.0/IDescrambler.h>
     28 #include <android/hardware/cas/native/1.0/types.h>
     29 #include <binder/MemoryDealer.h>
     30 #include <hidl/HidlSupport.h>
     31 #include <hidl/HidlTransportSupport.h>
     32 #include <hidl/Status.h>
     33 #include <hidlmemory/FrameworkUtils.h>
     34 #include <utils/Condition.h>
     35 #include <utils/Mutex.h>
     36 
     37 #define CLEAR_KEY_SYSTEM_ID 0xF6D8
     38 #define INVALID_SYSTEM_ID 0
     39 #define WAIT_TIMEOUT 3000000000
     40 
     41 #define PROVISION_STR                                      \
     42     "{                                                   " \
     43     "  \"id\": 21140844,                                 " \
     44     "  \"name\": \"Test Title\",                         " \
     45     "  \"lowercase_organization_name\": \"Android\",     " \
     46     "  \"asset_key\": {                                  " \
     47     "  \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\"  " \
     48     "  },                                                " \
     49     "  \"cas_type\": 1,                                  " \
     50     "  \"track_types\": [ ]                              " \
     51     "}                                                   "
     52 
     53 using android::Condition;
     54 using android::hardware::cas::V1_0::ICas;
     55 using android::hardware::cas::V1_0::ICasListener;
     56 using android::hardware::cas::V1_0::IDescramblerBase;
     57 using android::hardware::cas::V1_0::Status;
     58 using android::hardware::cas::native::V1_0::IDescrambler;
     59 using android::hardware::cas::native::V1_0::SubSample;
     60 using android::hardware::cas::native::V1_0::SharedBuffer;
     61 using android::hardware::cas::native::V1_0::DestinationBuffer;
     62 using android::hardware::cas::native::V1_0::BufferType;
     63 using android::hardware::cas::native::V1_0::ScramblingControl;
     64 using android::hardware::cas::V1_0::IMediaCasService;
     65 using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
     66 using android::hardware::fromHeap;
     67 using android::hardware::hidl_vec;
     68 using android::hardware::hidl_string;
     69 using android::hardware::HidlMemory;
     70 using android::hardware::Return;
     71 using android::hardware::Void;
     72 using android::IMemory;
     73 using android::IMemoryHeap;
     74 using android::MemoryDealer;
     75 using android::Mutex;
     76 using android::sp;
     77 
     78 namespace {
     79 
     80 const uint8_t kEcmBinaryBuffer[] = {
     81     0x00, 0x00, 0x01, 0xf0, 0x00, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00,
     82     0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x27, 0x10, 0x02, 0x00,
     83     0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0x0e, 0xe3, 0x91, 0xbc, 0xfd, 0x05, 0xb1, 0x60, 0x4f,
     84     0x17, 0x82, 0xa4, 0x86, 0x9b, 0x23, 0x56, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
     85     0x27, 0x10, 0x02, 0x00, 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0xd7, 0x43, 0x62, 0xf8, 0x1c,
     86     0x62, 0x19, 0x05, 0xc7, 0x3a, 0x42, 0xcd, 0xfd, 0xd9, 0x13, 0x48,
     87 };
     88 
     89 const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
     90 
     91 const uint8_t kInBinaryBuffer[] = {
     92     0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb, 0x01,
     93     0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x8b,
     94     0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff,
     95     0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee,
     96     0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x34, 0x32,
     97     0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20,
     98     0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
     99     0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d,
    100     0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65,
    101     0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
    102     0x6d, 0x6c, 0x6e, 0x45, 0x21, 0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87,
    103     0x8f, 0x04, 0x49, 0xe5, 0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04,
    104     0x7e, 0x60, 0x5b, 0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14,
    105     0x08, 0xcb, 0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d,
    106     0xe3, 0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
    107     0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c, 0xe1,
    108     0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7, 0x45, 0x58,
    109     0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03, 0xaa, 0xe4, 0x32,
    110     0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49, 0xc8, 0xbf, 0xca, 0x8c,
    111     0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e, 0xb3, 0x2d, 0x1f, 0xb8, 0x35,
    112     0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72, 0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1,
    113     0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d, 0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54,
    114     0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e, 0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e,
    115     0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a, 0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b,
    116     0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46, 0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47,
    117     0x6a, 0x12, 0xfa, 0xc4, 0x33, 0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa,
    118     0x8e, 0xf1, 0xbc, 0x3d, 0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f,
    119     0x25, 0x24, 0x7c, 0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73,
    120     0xb1, 0x53, 0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d,
    121     0xb4, 0x5e, 0x8a, 0x16, 0x14, 0x54, 0x64, 0x6e, 0x00, 0x6b, 0x11, 0x59, 0x8a, 0x63, 0x38, 0x80,
    122     0x76, 0xc3, 0xd5, 0x59, 0xf7, 0x3f, 0xd2, 0xfa, 0xa5, 0xca, 0x82, 0xff, 0x4a, 0x62, 0xf0, 0xe3,
    123     0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46, 0x7c, 0x75,
    124     0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0, 0xc5, 0x4c, 0x24,
    125     0x0e, 0x65,
    126 };
    127 
    128 const uint8_t kOutRefBinaryBuffer[] = {
    129     0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb, 0x01,
    130     0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x8b,
    131     0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff,
    132     0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee,
    133     0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x34, 0x32,
    134     0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20,
    135     0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
    136     0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d,
    137     0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65,
    138     0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
    139     0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61,
    140     0x62, 0x61, 0x63, 0x3d, 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c,
    141     0x6f, 0x63, 0x6b, 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73,
    142     0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68,
    143     0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
    144     0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e, 0x30,
    145     0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x6d, 0x65,
    146     0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61,
    147     0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69, 0x73, 0x3d, 0x31, 0x20,
    148     0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64,
    149     0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61,
    150     0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d, 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d,
    151     0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74,
    152     0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68,
    153     0x65, 0x61, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c,
    154     0x69, 0x63, 0x65, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e,
    155     0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69,
    156     0x6e, 0x74, 0x65, 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72,
    157     0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73,
    158     0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
    159     0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
    160     0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30, 0x20, 0x6b,
    161     0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20, 0x73, 0x63, 0x65,
    162     0x6e, 0x65,
    163 };
    164 
    165 class MediaCasListener : public ICasListener {
    166    public:
    167     virtual Return<void> onEvent(int32_t event, int32_t arg,
    168                                  const hidl_vec<uint8_t>& data) override {
    169         android::Mutex::Autolock autoLock(mMsgLock);
    170         mEvent = event;
    171         mEventArg = arg;
    172         mEventData = data;
    173 
    174         mEventReceived = true;
    175         mMsgCondition.signal();
    176         return Void();
    177     }
    178 
    179     void testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
    180                        hidl_vec<uint8_t>& eventData);
    181 
    182    private:
    183     int32_t mEvent = -1;
    184     int32_t mEventArg = -1;
    185     bool mEventReceived = false;
    186     hidl_vec<uint8_t> mEventData;
    187     android::Mutex mMsgLock;
    188     android::Condition mMsgCondition;
    189 };
    190 
    191 void MediaCasListener::testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
    192                                      hidl_vec<uint8_t>& eventData) {
    193     mEventReceived = false;
    194     auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
    195     EXPECT_TRUE(returnStatus.isOk());
    196     EXPECT_EQ(Status::OK, returnStatus);
    197 
    198     android::Mutex::Autolock autoLock(mMsgLock);
    199     while (!mEventReceived) {
    200         if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
    201             EXPECT_TRUE(false) << "event not received within timeout";
    202             return;
    203         }
    204     }
    205 
    206     EXPECT_EQ(mEvent, event);
    207     EXPECT_EQ(mEventArg, eventArg);
    208     EXPECT_TRUE(mEventData == eventData);
    209 }
    210 
    211 // Test environment for Cas HIDL HAL.
    212 class CasHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    213    public:
    214     // get the test environment singleton
    215     static CasHidlEnvironment* Instance() {
    216         static CasHidlEnvironment* instance = new CasHidlEnvironment;
    217         return instance;
    218     }
    219 
    220     virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
    221 };
    222 
    223 class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    224    public:
    225     virtual void SetUp() override {
    226         mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>(
    227             CasHidlEnvironment::Instance()->getServiceName<IMediaCasService>());
    228         ASSERT_NE(mService, nullptr);
    229     }
    230 
    231     sp<IMediaCasService> mService;
    232 
    233    protected:
    234     static void description(const std::string& description) {
    235         RecordProperty("description", description);
    236     }
    237 
    238     sp<ICas> mMediaCas;
    239     sp<IDescramblerBase> mDescramblerBase;
    240     sp<MediaCasListener> mCasListener;
    241     typedef struct _OobInputTestParams {
    242         const SubSample* subSamples;
    243         uint32_t numSubSamples;
    244         size_t imemSizeActual;
    245         uint64_t imemOffset;
    246         uint64_t imemSize;
    247         uint64_t srcOffset;
    248         uint64_t dstOffset;
    249     } OobInputTestParams;
    250 
    251     ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
    252     ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
    253     ::testing::AssertionResult descrambleTestInputBuffer(
    254             const sp<IDescrambler>& descrambler,
    255             Status* descrambleStatus,
    256             sp<IMemory>* hidlInMemory);
    257     ::testing::AssertionResult descrambleTestOobInput(
    258             const sp<IDescrambler>& descrambler,
    259             Status* descrambleStatus,
    260             const OobInputTestParams& params);
    261 };
    262 
    263 ::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
    264     auto status = mService->isSystemIdSupported(caSystemId);
    265     if (!status.isOk() || !status) {
    266         return ::testing::AssertionFailure();
    267     }
    268     status = mService->isDescramblerSupported(caSystemId);
    269     if (!status.isOk() || !status) {
    270         return ::testing::AssertionFailure();
    271     }
    272 
    273     mCasListener = new MediaCasListener();
    274     auto pluginStatus = mService->createPlugin(caSystemId, mCasListener);
    275     if (!pluginStatus.isOk()) {
    276         return ::testing::AssertionFailure();
    277     }
    278     mMediaCas = pluginStatus;
    279     if (mMediaCas == nullptr) {
    280         return ::testing::AssertionFailure();
    281     }
    282 
    283     auto descramblerStatus = mService->createDescrambler(caSystemId);
    284     if (!descramblerStatus.isOk()) {
    285         return ::testing::AssertionFailure();
    286     }
    287     mDescramblerBase = descramblerStatus;
    288     return ::testing::AssertionResult(mDescramblerBase != nullptr);
    289 }
    290 
    291 ::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
    292     Status sessionStatus;
    293     auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
    294         sessionStatus = status;
    295         *sessionId = id;
    296     });
    297     return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
    298 }
    299 
    300 ::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
    301     const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
    302     hidl_vec<SubSample> hidlSubSamples;
    303     hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
    304                                  (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
    305 
    306     sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
    307     if (nullptr == dealer.get()) {
    308         ALOGE("couldn't get MemoryDealer!");
    309         return ::testing::AssertionFailure();
    310     }
    311 
    312     sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
    313     if (nullptr == mem.get()) {
    314         ALOGE("couldn't allocate IMemory!");
    315         return ::testing::AssertionFailure();
    316     }
    317     *inMemory = mem;
    318 
    319     // build HidlMemory from memory heap
    320     ssize_t offset;
    321     size_t size;
    322     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
    323     if (nullptr == heap.get()) {
    324         ALOGE("couldn't get memory heap!");
    325         return ::testing::AssertionFailure();
    326     }
    327 
    328     uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
    329     memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
    330 
    331     // hidlMemory is not to be passed out of scope!
    332     sp<HidlMemory> hidlMemory = fromHeap(heap);
    333 
    334     SharedBuffer srcBuffer = {
    335             .heapBase = *hidlMemory,
    336             .offset = (uint64_t) offset,
    337             .size = (uint64_t) size
    338     };
    339 
    340     DestinationBuffer dstBuffer;
    341     dstBuffer.type = BufferType::SHARED_MEMORY;
    342     dstBuffer.nonsecureMemory = srcBuffer;
    343 
    344     uint32_t outBytes;
    345     hidl_string detailedError;
    346     auto returnVoid = descrambler->descramble(
    347         ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
    348         [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
    349             *descrambleStatus = status;
    350             outBytes = bytesWritten;
    351             detailedError = detailedErr;
    352         });
    353     if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
    354         ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
    355               returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
    356     }
    357     return ::testing::AssertionResult(returnVoid.isOk());
    358 }
    359 
    360 ::testing::AssertionResult MediaCasHidlTest::descrambleTestOobInput(
    361         const sp<IDescrambler>& descrambler,
    362         Status* descrambleStatus,
    363         const OobInputTestParams& params) {
    364     hidl_vec<SubSample> hidlSubSamples;
    365     hidlSubSamples.setToExternal(
    366             const_cast<SubSample*>(params.subSamples), params.numSubSamples, false /*own*/);
    367 
    368     sp<MemoryDealer> dealer = new MemoryDealer(params.imemSizeActual, "vts-cas");
    369     if (nullptr == dealer.get()) {
    370         ALOGE("couldn't get MemoryDealer!");
    371         return ::testing::AssertionFailure();
    372     }
    373 
    374     sp<IMemory> mem = dealer->allocate(params.imemSizeActual);
    375     if (nullptr == mem.get()) {
    376         ALOGE("couldn't allocate IMemory!");
    377         return ::testing::AssertionFailure();
    378     }
    379 
    380     // build HidlMemory from memory heap
    381     ssize_t offset;
    382     size_t size;
    383     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
    384     if (nullptr == heap.get()) {
    385         ALOGE("couldn't get memory heap!");
    386         return ::testing::AssertionFailure();
    387     }
    388 
    389     // hidlMemory is not to be passed out of scope!
    390     sp<HidlMemory> hidlMemory = fromHeap(heap);
    391 
    392     SharedBuffer srcBuffer = {
    393             .heapBase = *hidlMemory,
    394             .offset = (uint64_t) offset + params.imemOffset,
    395             .size = (uint64_t) params.imemSize,
    396     };
    397 
    398     DestinationBuffer dstBuffer;
    399     dstBuffer.type = BufferType::SHARED_MEMORY;
    400     dstBuffer.nonsecureMemory = srcBuffer;
    401 
    402     uint32_t outBytes;
    403     hidl_string detailedError;
    404     auto returnVoid = descrambler->descramble(
    405         ScramblingControl::EVENKEY /*2*/, hidlSubSamples,
    406         srcBuffer,
    407         params.srcOffset,
    408         dstBuffer,
    409         params.dstOffset,
    410         [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
    411             *descrambleStatus = status;
    412             outBytes = bytesWritten;
    413             detailedError = detailedErr;
    414         });
    415     if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
    416         ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
    417               returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
    418     }
    419     return ::testing::AssertionResult(returnVoid.isOk());
    420 }
    421 
    422 TEST_F(MediaCasHidlTest, EnumeratePlugins) {
    423     description("Test enumerate plugins");
    424     hidl_vec<HidlCasPluginDescriptor> descriptors;
    425     EXPECT_TRUE(mService
    426                     ->enumeratePlugins([&descriptors](
    427                         hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
    428                     .isOk());
    429 
    430     if (descriptors.size() == 0) {
    431         ALOGW("[   WARN   ] enumeratePlugins list empty");
    432         return;
    433     }
    434 
    435     sp<MediaCasListener> casListener = new MediaCasListener();
    436     for (size_t i = 0; i < descriptors.size(); i++) {
    437         int32_t caSystemId = descriptors[i].caSystemId;
    438 
    439         ASSERT_TRUE(createCasPlugin(caSystemId));
    440     }
    441 }
    442 
    443 TEST_F(MediaCasHidlTest, TestInvalidSystemIdFails) {
    444     description("Test failure for invalid system ID");
    445     sp<MediaCasListener> casListener = new MediaCasListener();
    446 
    447     ASSERT_FALSE(mService->isSystemIdSupported(INVALID_SYSTEM_ID));
    448     ASSERT_FALSE(mService->isDescramblerSupported(INVALID_SYSTEM_ID));
    449 
    450     auto pluginStatus = mService->createPlugin(INVALID_SYSTEM_ID, casListener);
    451     ASSERT_TRUE(pluginStatus.isOk());
    452     sp<ICas> mediaCas = pluginStatus;
    453     EXPECT_EQ(mediaCas, nullptr);
    454 
    455     auto descramblerStatus = mService->createDescrambler(INVALID_SYSTEM_ID);
    456     ASSERT_TRUE(descramblerStatus.isOk());
    457     sp<IDescramblerBase> descramblerBase = descramblerStatus;
    458     EXPECT_EQ(descramblerBase, nullptr);
    459 }
    460 
    461 TEST_F(MediaCasHidlTest, TestClearKeyPluginInstalled) {
    462     description("Test if ClearKey plugin is installed");
    463     hidl_vec<HidlCasPluginDescriptor> descriptors;
    464     EXPECT_TRUE(mService
    465                     ->enumeratePlugins([&descriptors](
    466                         hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
    467                     .isOk());
    468 
    469     if (descriptors.size() == 0) {
    470         ALOGW("[   WARN   ] enumeratePlugins list empty");
    471     }
    472 
    473     for (size_t i = 0; i < descriptors.size(); i++) {
    474         int32_t caSystemId = descriptors[i].caSystemId;
    475         if (CLEAR_KEY_SYSTEM_ID == caSystemId) {
    476             return;
    477         }
    478     }
    479 
    480     ASSERT_TRUE(false) << "ClearKey plugin not installed";
    481 }
    482 
    483 TEST_F(MediaCasHidlTest, TestClearKeyApis) {
    484     description("Test that valid call sequences succeed");
    485 
    486     ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
    487 
    488     auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
    489     EXPECT_TRUE(returnStatus.isOk());
    490     EXPECT_EQ(Status::OK, returnStatus);
    491 
    492     hidl_vec<uint8_t> hidlPvtData;
    493     hidlPvtData.resize(256);
    494     returnStatus = mMediaCas->setPrivateData(hidlPvtData);
    495     EXPECT_TRUE(returnStatus.isOk());
    496     EXPECT_EQ(Status::OK, returnStatus);
    497 
    498     std::vector<uint8_t> sessionId;
    499     ASSERT_TRUE(openCasSession(&sessionId));
    500     returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
    501     EXPECT_TRUE(returnStatus.isOk());
    502     EXPECT_EQ(Status::OK, returnStatus);
    503 
    504     std::vector<uint8_t> streamSessionId;
    505     ASSERT_TRUE(openCasSession(&streamSessionId));
    506     returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
    507     EXPECT_TRUE(returnStatus.isOk());
    508     EXPECT_EQ(Status::OK, returnStatus);
    509 
    510     returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
    511     EXPECT_TRUE(returnStatus.isOk());
    512     EXPECT_EQ(Status::OK, returnStatus);
    513 
    514     returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
    515     EXPECT_TRUE(returnStatus.isOk());
    516     EXPECT_EQ(Status::OK, returnStatus);
    517 
    518     hidl_vec<uint8_t> hidlNullPtr;
    519     hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
    520     returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
    521     EXPECT_TRUE(returnStatus.isOk());
    522     EXPECT_EQ(Status::OK, returnStatus);
    523 
    524     uint8_t refreshData[] = {0, 1, 2, 3};
    525     hidl_vec<uint8_t> hidlRefreshData;
    526     hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
    527     returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
    528     EXPECT_TRUE(returnStatus.isOk());
    529     EXPECT_EQ(Status::OK, returnStatus);
    530 
    531     int32_t eventID = 1;
    532     int32_t eventArg = 2;
    533     mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
    534 
    535     eventID = 3;
    536     eventArg = 4;
    537     uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
    538     hidl_vec<uint8_t> hidlEventData;
    539     hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
    540     mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
    541 
    542     uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
    543     hidl_vec<uint8_t> hidlClearKeyEmm;
    544     hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
    545     returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
    546     EXPECT_TRUE(returnStatus.isOk());
    547     EXPECT_EQ(Status::OK, returnStatus);
    548 
    549     hidl_vec<uint8_t> hidlEcm;
    550     hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
    551     returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
    552     EXPECT_TRUE(returnStatus.isOk());
    553     EXPECT_EQ(Status::OK, returnStatus);
    554     returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
    555     EXPECT_TRUE(returnStatus.isOk());
    556     EXPECT_EQ(Status::OK, returnStatus);
    557 
    558     EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
    559 
    560     sp<IDescrambler> descrambler;
    561     descrambler = IDescrambler::castFrom(mDescramblerBase);
    562     ASSERT_NE(descrambler, nullptr);
    563 
    564     Status descrambleStatus = Status::OK;
    565     sp<IMemory> dataMemory;
    566 
    567     ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
    568     EXPECT_EQ(Status::OK, descrambleStatus);
    569 
    570     ASSERT_NE(nullptr, dataMemory.get());
    571     uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->pointer()));
    572 
    573     int compareResult =
    574         memcmp(static_cast<const void*>(opBuffer), static_cast<const void*>(kOutRefBinaryBuffer),
    575                sizeof(kOutRefBinaryBuffer));
    576     EXPECT_EQ(0, compareResult);
    577 
    578     returnStatus = mDescramblerBase->release();
    579     EXPECT_TRUE(returnStatus.isOk());
    580     EXPECT_EQ(Status::OK, returnStatus);
    581 
    582     returnStatus = mMediaCas->release();
    583     EXPECT_TRUE(returnStatus.isOk());
    584     EXPECT_EQ(Status::OK, returnStatus);
    585 }
    586 
    587 TEST_F(MediaCasHidlTest, TestClearKeySessionClosedAfterRelease) {
    588     description("Test that all sessions are closed after a MediaCas object is released");
    589 
    590     ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
    591 
    592     auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
    593     EXPECT_TRUE(returnStatus.isOk());
    594     EXPECT_EQ(Status::OK, returnStatus);
    595 
    596     std::vector<uint8_t> sessionId;
    597     ASSERT_TRUE(openCasSession(&sessionId));
    598     std::vector<uint8_t> streamSessionId;
    599     ASSERT_TRUE(openCasSession(&streamSessionId));
    600 
    601     returnStatus = mMediaCas->release();
    602     EXPECT_TRUE(returnStatus.isOk());
    603     EXPECT_EQ(Status::OK, returnStatus);
    604 
    605     returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
    606     EXPECT_TRUE(returnStatus.isOk());
    607     EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
    608 
    609     returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
    610     EXPECT_TRUE(returnStatus.isOk());
    611     EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
    612 }
    613 
    614 TEST_F(MediaCasHidlTest, TestClearKeyErrors) {
    615     description("Test that invalid call sequences fail with expected error codes");
    616 
    617     ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
    618 
    619     /*
    620      * Test MediaCas error codes
    621      */
    622     // Provision should fail with an invalid asset string
    623     auto returnStatus = mMediaCas->provision(hidl_string("invalid asset string"));
    624     EXPECT_TRUE(returnStatus.isOk());
    625     EXPECT_EQ(Status::ERROR_CAS_NO_LICENSE, returnStatus);
    626 
    627     // Open a session, then close it so that it should become invalid
    628     std::vector<uint8_t> invalidSessionId;
    629     ASSERT_TRUE(openCasSession(&invalidSessionId));
    630     returnStatus = mMediaCas->closeSession(invalidSessionId);
    631     EXPECT_TRUE(returnStatus.isOk());
    632     EXPECT_EQ(Status::OK, returnStatus);
    633 
    634     // processEcm should fail with an invalid session id
    635     hidl_vec<uint8_t> hidlEcm;
    636     hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
    637     returnStatus = mMediaCas->processEcm(invalidSessionId, hidlEcm);
    638     EXPECT_TRUE(returnStatus.isOk());
    639     EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
    640 
    641     std::vector<uint8_t> sessionId;
    642     ASSERT_TRUE(openCasSession(&sessionId));
    643 
    644     // processEcm should fail without provisioning
    645     hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
    646     returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
    647     EXPECT_TRUE(returnStatus.isOk());
    648     EXPECT_EQ(Status::ERROR_CAS_NOT_PROVISIONED, returnStatus);
    649 
    650     returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
    651     EXPECT_TRUE(returnStatus.isOk());
    652     EXPECT_EQ(Status::OK, returnStatus);
    653 
    654     // processEcm should fail with ecm buffer that's too short
    655     hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), 8);
    656     returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
    657     EXPECT_TRUE(returnStatus.isOk());
    658     EXPECT_EQ(Status::BAD_VALUE, returnStatus);
    659 
    660     // processEcm should fail with ecm with bad descriptor count
    661     uint8_t badDescriptor[sizeof(kEcmBinaryBuffer)];
    662     memcpy(badDescriptor, kEcmBinaryBuffer, sizeof(kEcmBinaryBuffer));
    663     badDescriptor[17] = 0x03;  // change the descriptor count field to 3 (invalid)
    664     hidlEcm.setToExternal(static_cast<uint8_t*>(badDescriptor), sizeof(badDescriptor));
    665     returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
    666     EXPECT_TRUE(returnStatus.isOk());
    667     EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus);
    668 
    669     /*
    670      * Test MediaDescrambler error codes
    671      */
    672     // setMediaCasSession should fail with an invalid session id
    673     returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId);
    674     EXPECT_TRUE(returnStatus.isOk());
    675     EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
    676 
    677     // descramble should fail without a valid session
    678     sp<IDescrambler> descrambler;
    679     descrambler = IDescrambler::castFrom(mDescramblerBase);
    680     ASSERT_NE(descrambler, nullptr);
    681 
    682     Status descrambleStatus = Status::OK;
    683     sp<IMemory> dataMemory;
    684 
    685     ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
    686     EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus);
    687 
    688     // Now set a valid session, should still fail because no valid ecm is processed
    689     returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
    690     EXPECT_TRUE(returnStatus.isOk());
    691     EXPECT_EQ(Status::OK, returnStatus);
    692 
    693     ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
    694     EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus);
    695 
    696     // Verify that requiresSecureDecoderComponent handles empty mime
    697     EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent(""));
    698 
    699     // Verify that requiresSecureDecoderComponent handles invalid mime
    700     EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad"));
    701 }
    702 
    703 TEST_F(MediaCasHidlTest, TestClearKeyOobFails) {
    704     description("Test that oob descramble request fails with expected error");
    705 
    706     ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
    707 
    708     auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
    709     EXPECT_TRUE(returnStatus.isOk());
    710     EXPECT_EQ(Status::OK, returnStatus);
    711 
    712     std::vector<uint8_t> sessionId;
    713     ASSERT_TRUE(openCasSession(&sessionId));
    714 
    715     returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
    716     EXPECT_TRUE(returnStatus.isOk());
    717     EXPECT_EQ(Status::OK, returnStatus);
    718 
    719     hidl_vec<uint8_t> hidlEcm;
    720     hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
    721     returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
    722     EXPECT_TRUE(returnStatus.isOk());
    723     EXPECT_EQ(Status::OK, returnStatus);
    724 
    725     sp<IDescrambler> descrambler = IDescrambler::castFrom(mDescramblerBase);
    726     ASSERT_NE(nullptr, descrambler.get());
    727 
    728     Status descrambleStatus = Status::OK;
    729 
    730     // test invalid src buffer offset
    731     ASSERT_TRUE(descrambleTestOobInput(
    732             descrambler,
    733             &descrambleStatus,
    734             {
    735                 .subSamples     = kSubSamples,
    736                 .numSubSamples  = sizeof(kSubSamples)/sizeof(SubSample),
    737                 .imemSizeActual = sizeof(kInBinaryBuffer),
    738                 .imemOffset     = 0xcccccc,
    739                 .imemSize       = sizeof(kInBinaryBuffer),
    740                 .srcOffset      = 0,
    741                 .dstOffset      = 0
    742             }));
    743     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    744 
    745     // test invalid src buffer size
    746     ASSERT_TRUE(descrambleTestOobInput(
    747             descrambler,
    748             &descrambleStatus,
    749             {
    750                 .subSamples     = kSubSamples,
    751                 .numSubSamples  = sizeof(kSubSamples)/sizeof(SubSample),
    752                 .imemSizeActual = sizeof(kInBinaryBuffer),
    753                 .imemOffset     = 0,
    754                 .imemSize       = 0xcccccc,
    755                 .srcOffset      = 0,
    756                 .dstOffset      = 0
    757             }));
    758     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    759 
    760     // test invalid src buffer size
    761     ASSERT_TRUE(descrambleTestOobInput(
    762             descrambler,
    763             &descrambleStatus,
    764             {
    765                 .subSamples     = kSubSamples,
    766                 .numSubSamples  = sizeof(kSubSamples)/sizeof(SubSample),
    767                 .imemSizeActual = sizeof(kInBinaryBuffer),
    768                 .imemOffset     = 1,
    769                 .imemSize       = (uint64_t)-1,
    770                 .srcOffset      = 0,
    771                 .dstOffset      = 0
    772             }));
    773     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    774 
    775     // test invalid srcOffset
    776     ASSERT_TRUE(descrambleTestOobInput(
    777             descrambler,
    778             &descrambleStatus,
    779             {
    780                 .subSamples     = kSubSamples,
    781                 .numSubSamples  = sizeof(kSubSamples)/sizeof(SubSample),
    782                 .imemSizeActual = sizeof(kInBinaryBuffer),
    783                 .imemOffset     = 0,
    784                 .imemSize       = sizeof(kInBinaryBuffer),
    785                 .srcOffset      = 0xcccccc,
    786                 .dstOffset      = 0
    787             }));
    788     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    789 
    790     // test invalid dstOffset
    791     ASSERT_TRUE(descrambleTestOobInput(
    792             descrambler,
    793             &descrambleStatus,
    794             {
    795                 .subSamples     = kSubSamples,
    796                 .numSubSamples  = sizeof(kSubSamples)/sizeof(SubSample),
    797                 .imemSizeActual = sizeof(kInBinaryBuffer),
    798                 .imemOffset     = 0,
    799                 .imemSize       = sizeof(kInBinaryBuffer),
    800                 .srcOffset      = 0,
    801                 .dstOffset      = 0xcccccc
    802             }));
    803     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    804 
    805     // test detection of oob subsample sizes
    806     const SubSample invalidSubSamples1[] =
    807         {{162, 0}, {0, 184}, {0, 0xdddddd}};
    808 
    809     ASSERT_TRUE(descrambleTestOobInput(
    810             descrambler,
    811             &descrambleStatus,
    812             {
    813                 .subSamples     = invalidSubSamples1,
    814                 .numSubSamples  = sizeof(invalidSubSamples1)/sizeof(SubSample),
    815                 .imemSizeActual = sizeof(kInBinaryBuffer),
    816                 .imemOffset     = 0,
    817                 .imemSize       = sizeof(kInBinaryBuffer),
    818                 .srcOffset      = 0,
    819                 .dstOffset      = 0
    820             }));
    821     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    822 
    823     // test detection of overflowing subsample sizes
    824     const SubSample invalidSubSamples2[] =
    825         {{162, 0}, {0, 184}, {2, (uint32_t)-1}};
    826 
    827     ASSERT_TRUE(descrambleTestOobInput(
    828             descrambler,
    829             &descrambleStatus,
    830             {
    831                 .subSamples     = invalidSubSamples2,
    832                 .numSubSamples  = sizeof(invalidSubSamples2)/sizeof(SubSample),
    833                 .imemSizeActual = sizeof(kInBinaryBuffer),
    834                 .imemOffset     = 0,
    835                 .imemSize       = sizeof(kInBinaryBuffer),
    836                 .srcOffset      = 0,
    837                 .dstOffset      = 0
    838             }));
    839     EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
    840 
    841     returnStatus = mDescramblerBase->release();
    842     EXPECT_TRUE(returnStatus.isOk());
    843     EXPECT_EQ(Status::OK, returnStatus);
    844 
    845     returnStatus = mMediaCas->release();
    846     EXPECT_TRUE(returnStatus.isOk());
    847     EXPECT_EQ(Status::OK, returnStatus);
    848 }
    849 
    850 }  // anonymous namespace
    851 
    852 int main(int argc, char** argv) {
    853     ::testing::AddGlobalTestEnvironment(CasHidlEnvironment::Instance());
    854     ::testing::InitGoogleTest(&argc, argv);
    855     CasHidlEnvironment::Instance()->init(&argc, argv);
    856     int status = RUN_ALL_TESTS();
    857     LOG(INFO) << "Test result = " << status;
    858     return status;
    859 }
    860