1 /*
2 * Copyright (C) 2019 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/IDescramblerBase.h>
23 #include <android/hardware/cas/1.0/types.h>
24 #include <android/hardware/cas/1.1/ICas.h>
25 #include <android/hardware/cas/1.1/ICasListener.h>
26 #include <android/hardware/cas/1.1/IMediaCasService.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::IMemory;
55 using android::IMemoryHeap;
56 using android::MemoryDealer;
57 using android::Mutex;
58 using android::sp;
59 using android::hardware::fromHeap;
60 using android::hardware::hidl_string;
61 using android::hardware::hidl_vec;
62 using android::hardware::HidlMemory;
63 using android::hardware::Return;
64 using android::hardware::Void;
65 using android::hardware::cas::native::V1_0::BufferType;
66 using android::hardware::cas::native::V1_0::DestinationBuffer;
67 using android::hardware::cas::native::V1_0::IDescrambler;
68 using android::hardware::cas::native::V1_0::ScramblingControl;
69 using android::hardware::cas::native::V1_0::SharedBuffer;
70 using android::hardware::cas::native::V1_0::SubSample;
71 using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
72 using android::hardware::cas::V1_0::IDescramblerBase;
73 using android::hardware::cas::V1_0::Status;
74 using android::hardware::cas::V1_1::ICas;
75 using android::hardware::cas::V1_1::ICasListener;
76 using android::hardware::cas::V1_1::IMediaCasService;
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,
93 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
94 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
95 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
96 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
97 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
98 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
99 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
100 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
101 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
102 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x6e, 0x45, 0x21,
103 0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87, 0x8f, 0x04, 0x49, 0xe5,
104 0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04, 0x7e, 0x60, 0x5b,
105 0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14, 0x08, 0xcb,
106 0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d, 0xe3,
107 0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
108 0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c,
109 0xe1, 0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7,
110 0x45, 0x58, 0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03,
111 0xaa, 0xe4, 0x32, 0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49,
112 0xc8, 0xbf, 0xca, 0x8c, 0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e,
113 0xb3, 0x2d, 0x1f, 0xb8, 0x35, 0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72,
114 0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1, 0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d,
115 0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54, 0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e,
116 0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e, 0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a,
117 0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b, 0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46,
118 0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47, 0x6a, 0x12, 0xfa, 0xc4, 0x33,
119 0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa, 0x8e, 0xf1, 0xbc, 0x3d,
120 0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f, 0x25, 0x24, 0x7c,
121 0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73, 0xb1, 0x53,
122 0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d, 0xb4,
123 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,
125 0xe3, 0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46,
126 0x7c, 0x75, 0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0,
127 0xc5, 0x4c, 0x24, 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,
132 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
133 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
134 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
135 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
136 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
137 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
138 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
139 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
140 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
141 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
142 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
143 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
144 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
145 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
146 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
147 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
148 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
149 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
150 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
151 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
152 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
153 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
154 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
155 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
156 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
157 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
158 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
159 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
160 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
161 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
162 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
163 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
164 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
165 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
166 0x73, 0x63, 0x65, 0x6e, 0x65,
167 };
168
169 class MediaCasListener : public ICasListener {
170 public:
onEvent(int32_t event,int32_t arg,const hidl_vec<uint8_t> & data)171 virtual Return<void> onEvent(int32_t event, int32_t arg,
172 const hidl_vec<uint8_t>& data) override {
173 android::Mutex::Autolock autoLock(mMsgLock);
174 mEvent = event;
175 mEventArg = arg;
176 mEventData = data;
177
178 mEventReceived = true;
179 mMsgCondition.signal();
180 return Void();
181 }
182
onSessionEvent(const hidl_vec<uint8_t> & sessionId,int32_t event,int32_t arg,const hidl_vec<uint8_t> & data)183 virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& sessionId, int32_t event,
184 int32_t arg, const hidl_vec<uint8_t>& data) override {
185 android::Mutex::Autolock autoLock(mMsgLock);
186 mSessionId = sessionId;
187 mEvent = event;
188 mEventArg = arg;
189 mEventData = data;
190
191 mEventReceived = true;
192 mMsgCondition.signal();
193 return Void();
194 }
195
196 void testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
197 hidl_vec<uint8_t>& eventData);
198
199 void testSessionEventEcho(sp<ICas>& mediaCas, const hidl_vec<uint8_t>& sessionId,
200 int32_t& event, int32_t& eventArg, hidl_vec<uint8_t>& eventData);
201
202 private:
203 int32_t mEvent = -1;
204 int32_t mEventArg = -1;
205 bool mEventReceived = false;
206 hidl_vec<uint8_t> mEventData;
207 hidl_vec<uint8_t> mSessionId;
208 android::Mutex mMsgLock;
209 android::Condition mMsgCondition;
210 };
211
testEventEcho(sp<ICas> & mediaCas,int32_t & event,int32_t & eventArg,hidl_vec<uint8_t> & eventData)212 void MediaCasListener::testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
213 hidl_vec<uint8_t>& eventData) {
214 mEventReceived = false;
215 auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
216 EXPECT_TRUE(returnStatus.isOk());
217 EXPECT_EQ(Status::OK, returnStatus);
218
219 android::Mutex::Autolock autoLock(mMsgLock);
220 while (!mEventReceived) {
221 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
222 EXPECT_TRUE(false) << "event not received within timeout";
223 return;
224 }
225 }
226
227 EXPECT_EQ(mEvent, event);
228 EXPECT_EQ(mEventArg, eventArg);
229 EXPECT_TRUE(mEventData == eventData);
230 }
231
testSessionEventEcho(sp<ICas> & mediaCas,const hidl_vec<uint8_t> & sessionId,int32_t & event,int32_t & eventArg,hidl_vec<uint8_t> & eventData)232 void MediaCasListener::testSessionEventEcho(sp<ICas>& mediaCas, const hidl_vec<uint8_t>& sessionId,
233 int32_t& event, int32_t& eventArg,
234 hidl_vec<uint8_t>& eventData) {
235 mEventReceived = false;
236 auto returnStatus = mediaCas->sendSessionEvent(sessionId, event, eventArg, eventData);
237 EXPECT_TRUE(returnStatus.isOk());
238 EXPECT_EQ(Status::OK, returnStatus);
239
240 android::Mutex::Autolock autoLock(mMsgLock);
241 while (!mEventReceived) {
242 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
243 EXPECT_TRUE(false) << "event not received within timeout";
244 return;
245 }
246 }
247
248 EXPECT_TRUE(mSessionId == sessionId);
249 EXPECT_EQ(mEvent, event);
250 EXPECT_EQ(mEventArg, eventArg);
251 EXPECT_TRUE(mEventData == eventData);
252 }
253
254 // Test environment for Cas HIDL HAL.
255 class CasHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
256 public:
257 // get the test environment singleton
Instance()258 static CasHidlEnvironment* Instance() {
259 static CasHidlEnvironment* instance = new CasHidlEnvironment;
260 return instance;
261 }
262
registerTestServices()263 virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
264 };
265
266 class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
267 public:
SetUp()268 virtual void SetUp() override {
269 mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>(
270 CasHidlEnvironment::Instance()->getServiceName<IMediaCasService>());
271 ASSERT_NE(mService, nullptr);
272 }
273
274 sp<IMediaCasService> mService;
275
276 protected:
description(const std::string & description)277 static void description(const std::string& description) {
278 RecordProperty("description", description);
279 }
280
281 sp<ICas> mMediaCas;
282 sp<IDescramblerBase> mDescramblerBase;
283 sp<MediaCasListener> mCasListener;
284 typedef struct _OobInputTestParams {
285 const SubSample* subSamples;
286 uint32_t numSubSamples;
287 size_t imemSizeActual;
288 uint64_t imemOffset;
289 uint64_t imemSize;
290 uint64_t srcOffset;
291 uint64_t dstOffset;
292 } OobInputTestParams;
293
294 ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
295 ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
296 ::testing::AssertionResult descrambleTestInputBuffer(const sp<IDescrambler>& descrambler,
297 Status* descrambleStatus,
298 sp<IMemory>* hidlInMemory);
299 ::testing::AssertionResult descrambleTestOobInput(const sp<IDescrambler>& descrambler,
300 Status* descrambleStatus,
301 const OobInputTestParams& params);
302 };
303
createCasPlugin(int32_t caSystemId)304 ::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
305 auto status = mService->isSystemIdSupported(caSystemId);
306 if (!status.isOk() || !status) {
307 return ::testing::AssertionFailure();
308 }
309 status = mService->isDescramblerSupported(caSystemId);
310 if (!status.isOk() || !status) {
311 return ::testing::AssertionFailure();
312 }
313
314 mCasListener = new MediaCasListener();
315 auto pluginStatus = mService->createPluginExt(caSystemId, mCasListener);
316 if (!pluginStatus.isOk()) {
317 return ::testing::AssertionFailure();
318 }
319 mMediaCas = pluginStatus;
320 if (mMediaCas == nullptr) {
321 return ::testing::AssertionFailure();
322 }
323
324 auto descramblerStatus = mService->createDescrambler(caSystemId);
325 if (!descramblerStatus.isOk()) {
326 return ::testing::AssertionFailure();
327 }
328 mDescramblerBase = descramblerStatus;
329 return ::testing::AssertionResult(mDescramblerBase != nullptr);
330 }
331
openCasSession(std::vector<uint8_t> * sessionId)332 ::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
333 Status sessionStatus;
334 auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
335 sessionStatus = status;
336 *sessionId = id;
337 });
338 return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
339 }
340
descrambleTestInputBuffer(const sp<IDescrambler> & descrambler,Status * descrambleStatus,sp<IMemory> * inMemory)341 ::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
342 const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
343 hidl_vec<SubSample> hidlSubSamples;
344 hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
345 (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
346
347 sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
348 if (nullptr == dealer.get()) {
349 ALOGE("couldn't get MemoryDealer!");
350 return ::testing::AssertionFailure();
351 }
352
353 sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
354 if (nullptr == mem.get()) {
355 ALOGE("couldn't allocate IMemory!");
356 return ::testing::AssertionFailure();
357 }
358 *inMemory = mem;
359
360 // build HidlMemory from memory heap
361 ssize_t offset;
362 size_t size;
363 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
364 if (nullptr == heap.get()) {
365 ALOGE("couldn't get memory heap!");
366 return ::testing::AssertionFailure();
367 }
368
369 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
370 memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
371
372 // hidlMemory is not to be passed out of scope!
373 sp<HidlMemory> hidlMemory = fromHeap(heap);
374
375 SharedBuffer srcBuffer = {
376 .heapBase = *hidlMemory, .offset = (uint64_t)offset, .size = (uint64_t)size};
377
378 DestinationBuffer dstBuffer;
379 dstBuffer.type = BufferType::SHARED_MEMORY;
380 dstBuffer.nonsecureMemory = srcBuffer;
381
382 uint32_t outBytes;
383 hidl_string detailedError;
384 auto returnVoid = descrambler->descramble(
385 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
386 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
387 *descrambleStatus = status;
388 outBytes = bytesWritten;
389 detailedError = detailedErr;
390 });
391 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
392 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
393 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
394 }
395 return ::testing::AssertionResult(returnVoid.isOk());
396 }
397
descrambleTestOobInput(const sp<IDescrambler> & descrambler,Status * descrambleStatus,const OobInputTestParams & params)398 ::testing::AssertionResult MediaCasHidlTest::descrambleTestOobInput(
399 const sp<IDescrambler>& descrambler, Status* descrambleStatus,
400 const OobInputTestParams& params) {
401 hidl_vec<SubSample> hidlSubSamples;
402 hidlSubSamples.setToExternal(const_cast<SubSample*>(params.subSamples), params.numSubSamples,
403 false /*own*/);
404
405 sp<MemoryDealer> dealer = new MemoryDealer(params.imemSizeActual, "vts-cas");
406 if (nullptr == dealer.get()) {
407 ALOGE("couldn't get MemoryDealer!");
408 return ::testing::AssertionFailure();
409 }
410
411 sp<IMemory> mem = dealer->allocate(params.imemSizeActual);
412 if (nullptr == mem.get()) {
413 ALOGE("couldn't allocate IMemory!");
414 return ::testing::AssertionFailure();
415 }
416
417 // build HidlMemory from memory heap
418 ssize_t offset;
419 size_t size;
420 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
421 if (nullptr == heap.get()) {
422 ALOGE("couldn't get memory heap!");
423 return ::testing::AssertionFailure();
424 }
425
426 // hidlMemory is not to be passed out of scope!
427 sp<HidlMemory> hidlMemory = fromHeap(heap);
428
429 SharedBuffer srcBuffer = {
430 .heapBase = *hidlMemory,
431 .offset = (uint64_t)offset + params.imemOffset,
432 .size = (uint64_t)params.imemSize,
433 };
434
435 DestinationBuffer dstBuffer;
436 dstBuffer.type = BufferType::SHARED_MEMORY;
437 dstBuffer.nonsecureMemory = srcBuffer;
438
439 uint32_t outBytes;
440 hidl_string detailedError;
441 auto returnVoid = descrambler->descramble(
442 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, params.srcOffset,
443 dstBuffer, params.dstOffset,
444 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
445 *descrambleStatus = status;
446 outBytes = bytesWritten;
447 detailedError = detailedErr;
448 });
449 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
450 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
451 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
452 }
453 return ::testing::AssertionResult(returnVoid.isOk());
454 }
455
TEST_F(MediaCasHidlTest,TestClearKeyApisWithSession)456 TEST_F(MediaCasHidlTest, TestClearKeyApisWithSession) {
457 description("Test that valid call sequences with SessionEvent send and receive");
458
459 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
460
461 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
462 EXPECT_TRUE(returnStatus.isOk());
463 EXPECT_EQ(Status::OK, returnStatus);
464
465 hidl_vec<uint8_t> hidlPvtData;
466 hidlPvtData.resize(256);
467 returnStatus = mMediaCas->setPrivateData(hidlPvtData);
468 EXPECT_TRUE(returnStatus.isOk());
469 EXPECT_EQ(Status::OK, returnStatus);
470
471 std::vector<uint8_t> sessionId;
472 ASSERT_TRUE(openCasSession(&sessionId));
473 returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
474 EXPECT_TRUE(returnStatus.isOk());
475 EXPECT_EQ(Status::OK, returnStatus);
476
477 std::vector<uint8_t> streamSessionId;
478 ASSERT_TRUE(openCasSession(&streamSessionId));
479 returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
480 EXPECT_TRUE(returnStatus.isOk());
481 EXPECT_EQ(Status::OK, returnStatus);
482
483 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
484 EXPECT_TRUE(returnStatus.isOk());
485 EXPECT_EQ(Status::OK, returnStatus);
486
487 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
488 EXPECT_TRUE(returnStatus.isOk());
489 EXPECT_EQ(Status::OK, returnStatus);
490
491 hidl_vec<uint8_t> hidlNullPtr;
492 hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
493 returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
494 EXPECT_TRUE(returnStatus.isOk());
495 EXPECT_EQ(Status::OK, returnStatus);
496
497 uint8_t refreshData[] = {0, 1, 2, 3};
498 hidl_vec<uint8_t> hidlRefreshData;
499 hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
500 returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
501 EXPECT_TRUE(returnStatus.isOk());
502 EXPECT_EQ(Status::OK, returnStatus);
503
504 int32_t eventID = 1;
505 int32_t eventArg = 2;
506 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
507 mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlNullPtr);
508
509 eventID = 3;
510 eventArg = 4;
511 uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
512 hidl_vec<uint8_t> hidlEventData;
513 hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
514 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
515 mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlEventData);
516
517 uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
518 hidl_vec<uint8_t> hidlClearKeyEmm;
519 hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
520 returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
521 EXPECT_TRUE(returnStatus.isOk());
522 EXPECT_EQ(Status::OK, returnStatus);
523
524 hidl_vec<uint8_t> hidlEcm;
525 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
526 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
527 EXPECT_TRUE(returnStatus.isOk());
528 EXPECT_EQ(Status::OK, returnStatus);
529 returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
530 EXPECT_TRUE(returnStatus.isOk());
531 EXPECT_EQ(Status::OK, returnStatus);
532
533 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
534
535 sp<IDescrambler> descrambler;
536 descrambler = IDescrambler::castFrom(mDescramblerBase);
537 ASSERT_NE(descrambler, nullptr);
538
539 Status descrambleStatus = Status::OK;
540 sp<IMemory> dataMemory;
541
542 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
543 EXPECT_EQ(Status::OK, descrambleStatus);
544
545 ASSERT_NE(nullptr, dataMemory.get());
546 uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->pointer()));
547
548 int compareResult =
549 memcmp(static_cast<const void*>(opBuffer),
550 static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
551 EXPECT_EQ(0, compareResult);
552
553 returnStatus = mDescramblerBase->release();
554 EXPECT_TRUE(returnStatus.isOk());
555 EXPECT_EQ(Status::OK, returnStatus);
556
557 returnStatus = mMediaCas->release();
558 EXPECT_TRUE(returnStatus.isOk());
559 EXPECT_EQ(Status::OK, returnStatus);
560 }
561
562 } // anonymous namespace
563
main(int argc,char ** argv)564 int main(int argc, char** argv) {
565 ::testing::AddGlobalTestEnvironment(CasHidlEnvironment::Instance());
566 ::testing::InitGoogleTest(&argc, argv);
567 CasHidlEnvironment::Instance()->init(&argc, argv);
568 int status = RUN_ALL_TESTS();
569 LOG(INFO) << "Test result = " << status;
570 return status;
571 }
572