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