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