• 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_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:
onEvent(int32_t event,int32_t arg,const hidl_vec<uint8_t> & data)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 
testEventEcho(sp<ICas> & mediaCas,int32_t & event,int32_t & eventArg,hidl_vec<uint8_t> & eventData)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
Instance()215     static CasHidlEnvironment* Instance() {
216         static CasHidlEnvironment* instance = new CasHidlEnvironment;
217         return instance;
218     }
219 
registerTestServices()220     virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
221 };
222 
223 class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
224    public:
SetUp()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:
description(const std::string & description)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 
createCasPlugin(int32_t caSystemId)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 
openCasSession(std::vector<uint8_t> * sessionId)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 
descrambleTestInputBuffer(const sp<IDescrambler> & descrambler,Status * descrambleStatus,sp<IMemory> * inMemory)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 
descrambleTestOobInput(const sp<IDescrambler> & descrambler,Status * descrambleStatus,const OobInputTestParams & params)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 
TEST_F(MediaCasHidlTest,EnumeratePlugins)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 
TEST_F(MediaCasHidlTest,TestInvalidSystemIdFails)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 
TEST_F(MediaCasHidlTest,TestClearKeyPluginInstalled)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 
TEST_F(MediaCasHidlTest,TestClearKeyApis)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 
TEST_F(MediaCasHidlTest,TestClearKeySessionClosedAfterRelease)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 
TEST_F(MediaCasHidlTest,TestClearKeyErrors)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 
TEST_F(MediaCasHidlTest,TestClearKeyOobFails)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 
main(int argc,char ** argv)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