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