blob: f436b8b5ee3a1a4033e7cc246d68c7a7824d57cf [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);
338 if (!status.isOk() || !status) {
339 return ::testing::AssertionFailure();
340 }
341 status = mService->isDescramblerSupported(caSystemId);
342 if (!status.isOk() || !status) {
343 return ::testing::AssertionFailure();
344 }
345
346 mCasListener = new MediaCasListener();
347 auto pluginStatus = mService->createPluginExt(caSystemId, mCasListener);
348 if (!pluginStatus.isOk()) {
349 return ::testing::AssertionFailure();
350 }
351 mMediaCas = ICas::castFrom(pluginStatus);
352 if (mMediaCas == nullptr) {
353 return ::testing::AssertionFailure();
354 }
355
356 auto descramblerStatus = mService->createDescrambler(caSystemId);
357 if (!descramblerStatus.isOk()) {
358 return ::testing::AssertionFailure();
359 }
360 mDescramblerBase = descramblerStatus;
361 return ::testing::AssertionResult(mDescramblerBase != nullptr);
362}
363
364::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
365 Status sessionStatus;
366 auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
367 sessionStatus = status;
368 *sessionId = id;
369 });
370 return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
371}
372
373::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
374 const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
375 hidl_vec<SubSample> hidlSubSamples;
376 hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
377 (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
378
379 sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
380 if (nullptr == dealer.get()) {
381 ALOGE("couldn't get MemoryDealer!");
382 return ::testing::AssertionFailure();
383 }
384
385 sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
386 if (nullptr == mem.get()) {
387 ALOGE("couldn't allocate IMemory!");
388 return ::testing::AssertionFailure();
389 }
390 *inMemory = mem;
391
392 // build HidlMemory from memory heap
393 ssize_t offset;
394 size_t size;
395 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
396 if (nullptr == heap.get()) {
397 ALOGE("couldn't get memory heap!");
398 return ::testing::AssertionFailure();
399 }
400
401 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->unsecurePointer()));
402 memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
403
404 // hidlMemory is not to be passed out of scope!
405 sp<HidlMemory> hidlMemory = fromHeap(heap);
406
407 SharedBuffer srcBuffer = {
408 .heapBase = *hidlMemory, .offset = (uint64_t)offset, .size = (uint64_t)size};
409
410 DestinationBuffer dstBuffer;
411 dstBuffer.type = BufferType::SHARED_MEMORY;
412 dstBuffer.nonsecureMemory = srcBuffer;
413
414 uint32_t outBytes;
415 hidl_string detailedError;
416 auto returnVoid = descrambler->descramble(
417 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
418 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
419 *descrambleStatus = status;
420 outBytes = bytesWritten;
421 detailedError = detailedErr;
422 });
423 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
424 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
425 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
426 }
427 return ::testing::AssertionResult(returnVoid.isOk());
428}
429
430::testing::AssertionResult MediaCasHidlTest::descrambleTestOobInput(
431 const sp<IDescrambler>& descrambler, Status* descrambleStatus,
432 const OobInputTestParams& params) {
433 hidl_vec<SubSample> hidlSubSamples;
434 hidlSubSamples.setToExternal(const_cast<SubSample*>(params.subSamples), params.numSubSamples,
435 false /*own*/);
436
437 sp<MemoryDealer> dealer = new MemoryDealer(params.imemSizeActual, "vts-cas");
438 if (nullptr == dealer.get()) {
439 ALOGE("couldn't get MemoryDealer!");
440 return ::testing::AssertionFailure();
441 }
442
443 sp<IMemory> mem = dealer->allocate(params.imemSizeActual);
444 if (nullptr == mem.get()) {
445 ALOGE("couldn't allocate IMemory!");
446 return ::testing::AssertionFailure();
447 }
448
449 // build HidlMemory from memory heap
450 ssize_t offset;
451 size_t size;
452 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
453 if (nullptr == heap.get()) {
454 ALOGE("couldn't get memory heap!");
455 return ::testing::AssertionFailure();
456 }
457
458 // hidlMemory is not to be passed out of scope!
459 sp<HidlMemory> hidlMemory = fromHeap(heap);
460
461 SharedBuffer srcBuffer = {
462 .heapBase = *hidlMemory,
463 .offset = (uint64_t)offset + params.imemOffset,
464 .size = (uint64_t)params.imemSize,
465 };
466
467 DestinationBuffer dstBuffer;
468 dstBuffer.type = BufferType::SHARED_MEMORY;
469 dstBuffer.nonsecureMemory = srcBuffer;
470
471 uint32_t outBytes;
472 hidl_string detailedError;
473 auto returnVoid = descrambler->descramble(
474 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, params.srcOffset,
475 dstBuffer, params.dstOffset,
476 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
477 *descrambleStatus = status;
478 outBytes = bytesWritten;
479 detailedError = detailedErr;
480 });
481 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
482 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
483 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
484 }
485 return ::testing::AssertionResult(returnVoid.isOk());
486}
487
Henry Fang93470542020-03-10 14:29:36 -0700488TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) {
Henry Fang9bed3dc2019-10-11 17:30:15 -0700489 description("Test that valid call sequences with SessionEvent send and receive");
490
491 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
492
493 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
494 EXPECT_TRUE(returnStatus.isOk());
495 EXPECT_EQ(Status::OK, returnStatus);
496
497 hidl_vec<uint8_t> hidlPvtData;
498 hidlPvtData.resize(256);
499 returnStatus = mMediaCas->setPrivateData(hidlPvtData);
500 EXPECT_TRUE(returnStatus.isOk());
501 EXPECT_EQ(Status::OK, returnStatus);
502
503 std::vector<uint8_t> sessionId;
504 ASSERT_TRUE(openCasSession(&sessionId));
505 returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
506 EXPECT_TRUE(returnStatus.isOk());
507 EXPECT_EQ(Status::OK, returnStatus);
508
509 std::vector<uint8_t> streamSessionId;
510 ASSERT_TRUE(openCasSession(&streamSessionId));
511 returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
512 EXPECT_TRUE(returnStatus.isOk());
513 EXPECT_EQ(Status::OK, returnStatus);
514
515 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
516 EXPECT_TRUE(returnStatus.isOk());
517 EXPECT_EQ(Status::OK, returnStatus);
518
519 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
520 EXPECT_TRUE(returnStatus.isOk());
521 EXPECT_EQ(Status::OK, returnStatus);
522
523 hidl_vec<uint8_t> hidlNullPtr;
524 hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
525 returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
526 EXPECT_TRUE(returnStatus.isOk());
527 EXPECT_EQ(Status::OK, returnStatus);
528
529 uint8_t refreshData[] = {0, 1, 2, 3};
530 hidl_vec<uint8_t> hidlRefreshData;
531 hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
532 returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
533 EXPECT_TRUE(returnStatus.isOk());
534 EXPECT_EQ(Status::OK, returnStatus);
535
536 int32_t eventID = 1;
537 int32_t eventArg = 2;
538 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
539 mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlNullPtr);
540
541 eventID = 3;
542 eventArg = 4;
543 uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
544 hidl_vec<uint8_t> hidlEventData;
545 hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
546 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
547 mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlEventData);
548
549 SessionIntent intent = SessionIntent::LIVE;
550 ScramblingMode mode = ScramblingMode::DVB_CSA1;
551 mCasListener->testStatusUpdate(mMediaCas, &sessionId, intent, mode);
552
553 uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
554 hidl_vec<uint8_t> hidlClearKeyEmm;
555 hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
556 returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
557 EXPECT_TRUE(returnStatus.isOk());
558 EXPECT_EQ(Status::OK, returnStatus);
559
560 hidl_vec<uint8_t> hidlEcm;
561 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
562 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
563 EXPECT_TRUE(returnStatus.isOk());
564 EXPECT_EQ(Status::OK, returnStatus);
565 returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
566 EXPECT_TRUE(returnStatus.isOk());
567 EXPECT_EQ(Status::OK, returnStatus);
568
569 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
570
571 sp<IDescrambler> descrambler;
572 descrambler = IDescrambler::castFrom(mDescramblerBase);
573 ASSERT_NE(descrambler, nullptr);
574
575 Status descrambleStatus = Status::OK;
576 sp<IMemory> dataMemory;
577
578 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
579 EXPECT_EQ(Status::OK, descrambleStatus);
580
581 ASSERT_NE(nullptr, dataMemory.get());
582 uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
583
584 int compareResult =
585 memcmp(static_cast<const void*>(opBuffer),
586 static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
587 EXPECT_EQ(0, compareResult);
588
589 returnStatus = mDescramblerBase->release();
590 EXPECT_TRUE(returnStatus.isOk());
591 EXPECT_EQ(Status::OK, returnStatus);
592
593 returnStatus = mMediaCas->release();
594 EXPECT_TRUE(returnStatus.isOk());
595 EXPECT_EQ(Status::OK, returnStatus);
596}
597
598} // anonymous namespace
599
Dan Shiff985a82020-07-29 09:45:03 -0700600GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCasHidlTest);
Henry Fang93470542020-03-10 14:29:36 -0700601INSTANTIATE_TEST_SUITE_P(
602 PerInstance, MediaCasHidlTest,
603 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)),
604 android::hardware::PrintInstanceNameToString);